Fliptile——搜索+二進制優化

【題目描述】

Farmer John knows that an intellectually satisfied cow is a happy cow who will give more milk. He has arranged a brainy activity for cows in which they manipulate an M × N grid (1 ≤ M ≤ 15; 1 ≤ N ≤ 15) of square tiles, each of which is colored black on one side and white on the other side.

As one would guess, when a single white tile is flipped, it changes to black; when a single black tile is flipped, it changes to white. The cows are rewarded when they flip the tiles so that each tile has the white side face up. However, the cows have rather large hooves and when they try to flip a certain tile, they also flip all the adjacent tiles (tiles that share a full edge with the flipped tile). Since the flips are tiring, the cows want to minimize the number of flips they have to make.Help the cows determine the minimum number of flips required, and the locations to flip to achieve that minimum. If there are multiple ways to achieve the task with the minimum amount of flips, return the one with the least lexicographical ordering in the output when considered as a string. If the task is impossible, print one line with the word "IMPOSSIBLE".

Input
Line 1: Two space-separated integers: M and N
Lines 2… M+1: Line i+1 describes the colors (left to right) of row i of the grid with N space-separated integers which are 1 for black and 0 for white
Output
Lines 1… M: Each line contains N space-separated integers, each specifying how many times to flip that particular location.
Sample Input

4 4
1 0 0 1
0 1 1 0
0 1 1 0
1 0 0 1

Sample Output

0 0 0 0
1 0 0 1
1 0 0 1
0 0 0 0

【題目分析】
看完題目后很明顯應該是一個暴力搜索,但是應該從哪里開始搜索呢?從頭開始的話會有215*15種可能,顯然是不允許的。我們應該優化一下搜索的順序,即哪些情況是顯然不可能成立的。
我們如果從上往下搜索,那么下面的對上面的影響只有四個方向中上面的那個,那么如果搜索在x行,那么x-1行中的1下面的那塊必須翻轉,0下面的那塊不能翻轉。這樣類推,我們發現除了第一行其他行的翻轉情況都已經被確定,因此我們只需要枚舉第一行的翻轉情況(215種)就可以了。
看大佬的博客發現用到一種二進制的優化。如果沒有這種優化的話我們可能需要搜索,相對比較復雜。
我們可以將一行中翻轉的情況看做一個數,例如:110就是翻轉前兩個,那么總共的情況就是1<<m種
對于一個數字,我們如何快速判斷哪些位是1呢?
我們可以用110與100,010,001的與判斷,如果與的結果是0則該位是0,如果結果不是0則該位是1
有上面的方法后我們就可以寫出程序啦
【AC代碼】(借鑒大佬)

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<climits>
#include<string>
#include<queue>
using namespace std;int n,m,num,cnt,ans;
const int MAXN=20;
int a[MAXN][MAXN];		//原數組
int b[MAXN][MAXN];		//用來修改的臨時數組
int c[MAXN][MAXN];		//保存答案
const int drc[5][2]={0,0,0,1,0,-1,1,0,-1,0};void rev(int i,int j)
{int u,v;++cnt;  c[i][j]=1;	//記錄答案for(int k=0;k<5;k++){u=i+drc[k][0]; v=j+drc[k][1];if(u<0 || u>=n || v<0 || v>=m) continue;b[u][v]^=1;	//翻轉}
}bool check(int x)
{cnt=0;memcpy(b,a,sizeof(b));	//直接將a拷貝給bfor(int i=0;i<m;i++){if(x&(1<<(m-1-i)))//1<<(m-1-i)是第i位為1其他位為0的數,用來判斷x在第i位是不是1rev(0,i);	//如果是1就翻轉}for(int i=1;i<n;i++){for(int j=0;j<m;j++){if(b[i-1][j]) rev(i,j);	//如果上一行是1就翻轉}}for(int i=0;i<m;i++){if(b[n-1][i]) return false;	//前面肯定都是0了,只需要判斷最后一行是不是0就可以了}return true;
}int main()
{scanf("%d%d",&n,&m);ans=INT_MAX; num=-1;memset(a,0,sizeof(a));for(int i=0;i<n;i++){for(int j=0;j<m;j++){scanf("%d",&a[i][j]);}}for(int i=0,j=1<<m;i<j;i++){if(check(i) && cnt<ans)	//這樣記錄的答案肯定是字典序,前面的能不翻就不翻,盡量翻后面的{ans=cnt; num=i;}}memset(c,0,sizeof(c));	//用來保存答案,之前都不用保存if(num!=-1){check(num);for(int i=0;i<n;i++){for(int j=0;j<m-1;j++){printf("%d ",c[i][j]);}printf("%d\n",c[i][m-1]);}}else{printf("IMPOSSIBLE");}return 0;
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/384157.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/384157.shtml
英文地址,請注明出處:http://en.pswp.cn/news/384157.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

掃雷

1.將掃雷界面看成一個二維數組,先對界面進行打印 2.置雷 3.排雷 4.對每次的結果進行游戲輸出 5.提醒用戶游戲輸贏 game.c #define _CRT_SECURE_NO_WARNINGS 1 #include"game.h" //初始化 void init_board(char mine[ROWS][COLS], int rows, int cols, char set) {in…

C相關練習題

1.調整數組使奇數全部都位于偶數前面。 輸入一個整數數組&#xff0c;實現一個函數&#xff0c;來調整該數組中數字的順序使得數組中所有的奇數位于數組的前半部分&#xff0c;所有偶數位于數組的后半部分。 #include<stdio.h> void range(int arr[], int sz) {int left…

【C語言】單鏈表的所有操作的實現(包括PopBack、PushBack、PopFront、PushFront、Insert)

http://blog.csdn.net/hanjing_1995/article/details/51539563 [cpp] view plaincopy #define _CRT_SECURE_NO_WARNINGS 1 #include<iostream> using namespace std; //單鏈表的實現 #include<assert.h> typedef int DataType; typedef…

Shuffle'm Up——簡單模擬

【題目描述】 A common pastime for poker players at a poker table is to shuffle stacks of chips. Shuffling chips is performed by starting with two stacks of poker chips, S1 and S2, each stack containing C chips. Each stack may contain chips of several diff…

C++ explicit關鍵字詳解

http://www.cnblogs.com/ymy124/p/3632634.html 首先, C中的explicit關鍵字只能用于修飾只有一個參數的類構造函數, 它的作用是表明該構造函數是顯示的, 而非隱式的, 跟它相對應的另一個關鍵字是implicit, 意思是隱藏的,類構造函數默認情況下即聲明為implicit(隱式). 那么顯示聲…

Fire!——兩個BFS

【題目描述】 【題目分析】 看到題目后很清楚是兩個BFS&#xff0c;可是我覺得對于火的BFS可以轉換成判斷&#xff0c;我的做法是將火的位置全部記錄下來&#xff0c;然后判斷某個位置距離每個火的步數是否小于當前步數&#xff0c;可是錯了&#xff0c;還不清楚為什么&#x…

函數調用過程(棧楨)

棧楨 首先來看一段代碼 #include<stdio.h> int add(int x, int y) {int z x y;return z; } int main() {int a 10;int b 20;int ret add(a, b);printf("ret %d\n",ret);return 0; } 此處是為了給a,b分別開辟空間,這時棧楨如圖所示 兩條push命令將a,b變…

C++智能指針簡單剖析

http://blog.csdn.net/lanxuezaipiao/article/details/41603883 導讀 最近在補看《C Primer Plus》第六版&#xff0c;這的確是本好書&#xff0c;其中關于智能指針的章節解析的非常清晰&#xff0c;一解我以前的多處困惑。C面試過程中&#xff0c;很多面試官都喜歡問智能指針相…

非常可樂——BFS

【題目描述】 大家一定覺的運動以后喝可樂是一件很愜意的事情&#xff0c;但是seeyou卻不這么認為。因為每次當seeyou買了可樂以后&#xff0c;阿牛就要求和seeyou一起分享這一瓶可樂&#xff0c;而且一定要喝的和seeyou一樣多。但seeyou的手中只有兩個杯子&#xff0c;它們的容…

整型數據存儲

//代碼1 #include<stdio.h> int main() {char a -1;signed char b -1;unsigned char c -1;printf("a %d, b %d, c %d", a, b, c);return 0; } 1000 0000 0000 0001 -> -1源碼 1111 1111 1111 1110 -> -1反碼 1111 1111 1111 1111 -> -1補碼 對于…

聊聊gcc參數中的-I, -L和-l

http://blog.csdn.net/stpeace/article/details/49408665 在本文中&#xff0c; 我們來聊聊gcc中三個常見的參數&#xff0c; 也即-I, -L和-l 一. 先說 -I (注意是大寫的i) 我們先來看簡單的程序&#xff1a; main.c: [cpp] view plaincopy #include <stdio.h> #incl…

Pots——BFS

【題目描述】 You are given two pots, having the volume of A and B liters respectively. The following operations can be performed: FILL(i) fill the pot i (1 ≤ i ≤ 2) from the tap; DROP(i) empty the pot i to the drain; POUR(i,j) pour from pot i to pot j;…

HDU - 4578Transformation——線段樹+區間加法修改+區間乘法修改+區間置數+區間和查詢+區間平方和查詢+區間立方和查詢

【題目描述】 HDU - 4578Transformation Problem Description Yuanfang is puzzled with the question below: There are n integers, a1, a2, …, an. The initial values of them are 0. There are four kinds of operations. Operation 1: Add c to each number between ax …

[C++基礎]034_C++模板編程里的主版本模板類、全特化、偏特化(C++ Type Traits)

http://www.cnblogs.com/alephsoul-alephsoul/archive/2012/10/18/2728753.html 1. 主版本模板類 首先我們來看一段初學者都能看懂&#xff0c;應用了模板的程序&#xff1a; 1 #include <iostream>2 using namespace std;3 4 template<class T1, class T2>5 clas…

自定義類型: 結構體,枚舉,聯合

1.結構體 個人認為結構體和數組特別相似&#xff0c;只不過結構體和數組的區別在于結構體的成員可以是不同類型&#xff0c;而數組成員類型是相同的。 &#xff08;1&#xff09;結構體的聲明 struct tag {成員列表//至少得有一個成員 }值列表;//值列表可以省略 struct {int a…

詳解C++中的函數調用和下標以及成員訪問運算符的重載

http://www.jb51.net/article/78436.htm 這篇文章主要介紹了詳解C中的函數調用和下標以及成員訪問運算符,講到了這些二元運算符使用的語法及重載,需要的朋友可以參考下函數調用 使用括號調用的函數調用運算符是二元運算符。 語法 ?1primary-expression ( expression-list )備…

A計劃——BFS

【題目描述】 可憐的公主在一次次被魔王擄走一次次被騎士們救回來之后&#xff0c;而今&#xff0c;不幸的她再一次面臨生命的考驗。魔王已經發出消息說將在T時刻吃掉公主&#xff0c;因為他聽信謠言說吃公主的肉也能長生不老。年邁的國王正是心急如焚&#xff0c;告招天下勇士…

使用openssl的md5庫

http://blog.csdn.net/sinat_35297665/article/details/78244523 在linux機器上&#xff0c;有一個命令可以計算出文件的md5值&#xff0c;那就是md5sum&#xff0c;如果沒有的話&#xff0c;就需要安裝RPM包&#xff1a;coreutils。 現在我們使用openssl的庫也可以方便的計算出…

主席樹入門

今天學習了一下主席樹&#xff08;名字這么強的嘛&#xff09; 雖然直接理解起來不容易&#xff0c;但是這種解決問題的思想其實并不陌生。 我們可以首先來看維護整個區間第K大的線段樹 我們將[l,r]區間內數字的多少用線段樹進行維護&#xff0c;這樣的話為了求取區間第k大&…

Socket網絡編程--小小網盤程序(1)

http://www.cnblogs.com/wunaozai/p/3886588.html 這個系列是準備講基于Linux Socket進行文件傳輸。簡單的文件傳輸就是客戶端可以上傳文件&#xff0c;可以從服務器端下載文件。就這么兩個功能如果再加上身份驗證&#xff0c;就成了FTP服務器了&#xff0c;如果對用戶的操作再…