POJ-3279-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
Translation:
Farmer John knows that a contented cow is a happy cow, and it will provide more milk. He arranged a mental activity for the cows to manipulate a M × N square brick grid (1 ≤ M ≤ 15; 1 ≤ N ≤ 15). One side of each square brick is black and the other is white.
As people have guessed, when a white tile is turned over, it will turn black; when a black tile is turned over, it will turn white. Cows will be rewarded for flipping tiles so that the white side of each tile faces up. However, cows have considerable hooves, and when they try to flip a tile, they also flip all adjacent tiles (tiles that share a full edge with the flipped tiles). Because the somersault is very tired, the cow wants to reduce the number of somersaults as much as possible.
Help the cow to determine the minimum number of turns required and the position of the turns to achieve the minimum. If there are multiple ways to accomplish the task with the minimum amount of flipping,
==Is considered to be the least lexicographic return in the output of the string. = =
If the task is not possible, print a line of "impossible".
input
Line 1: integers separated by two spaces: M and N
Line 2.. M + 1: line I + 1 represents the color of the first line of the grid (from left to right), which is represented by an integer separated by N spaces, 1 represents black, and 0 represents white
output
Line 1.. M: Each line contains N space delimited integers, each of which specifies the number of times to flip a specific 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
It bothered me for 10 hours, and finally I found that if the number of turns is the same, I need to output the dictionary order~~
Let's talk about the idea
1. The floor tiles in the previous row can be flipped by flipping the next row
2. The results of turning all odd times are the same, and even times are the same
First, traverse all the flipping results of the first line. After each traverse - > use the second line and every subsequent line to flip the bricks of the previous line or 1. At the end, judge the black and white of the last line. As long as there is one black, the result is wrong. If it is all white, it will be compared with the minimum steps. If it is smaller, it will be saved. If it is equal, compare the words of the two answers from 00 If the new result dictionary order is small, reset the answer;
**Global variable**
#include<stdio.h> #include<string.h> //Using memset #include<math.h> //pow will be used. int m,n; //Map ranks int map[20][20],a[20][20],b[20][20],ans[20][20],ann=0x3f3f3f3f; //Map is save map, a is zero time map, reset at the end of each traversal, b is save the bricks turned in this traversal, ans stores the answer with the smallest number of dictionaries and steps in all current answers int xyz[20]; //Save the binary number in the array, i.e., the 01 sequence with column length from 0000-1111
**Functions used**
int baoli(void); //main program void res(void); //Used to reset the map after each traversal and flipping void two(int); //Because to traverse all the flipped results of the first row, at most, i.e. 2 ^ 16 power, traverse 0-2 ^ 16 and turn to binary is 16 01 sequences void fan(int,int); //Flip function, used to flip up, down, left, right and himself int panduan(void); //Judge whether the last line is all white void zuihou(void); //To save answers int bijiao(void); //Dictionary order used to compare two answers
**main function**
int main() { int i,j; scanf("%d %d",&n,&m); for(i=1;i<=n;i++) { for(j=1;j<=m;j++) { scanf("%d",&map[i][j]); //Read the map and start from 1 to solve the problem of crossing the border in flipping } } res(); //Reset a to the same as map int p=baoli(); //Save main function return value if(p!=-1) //Output the answer directly if the return value is not - 1 { for(i=1;i<=n;i++) { for(j=1;j<=m;j++) { printf("%d ",ans[i][j]); } printf("\n"); } } else //Otherwise, emmm { printf("IMPOSSIBLE\n"); } return 0; }
Specific function implementation
** void res(void)**
void res(void) { int i,j; for(i=1;i<=n;i++) { for(j=1;j<=m;j++) { a[i][j]=map[i][j]; //Reset a to map } } return; }
void fan(int,int)
void fan(int x,int y) //Flipping function { a[x][y]=(a[x][y]+1)%2; //+1. Taking the remainder again is equivalent to reversing 01 a[x-1][y]=(a[x-1][y]+1)%2; a[x][y-1]=(a[x][y-1]+1)%2; a[x+1][y]=(a[x+1][y]+1)%2; a[x][y+1]=(a[x][y+1]+1)%2; return; }
int panduan(void)
int panduan(void) //It is used to judge whether there is black brick in the last line. If there is, return 0; otherwise, return 1 { int i,t=1; for(i=1;i<=m;i++) { if(a[n][i]==1) { t=0; break; } } return t; }
void two(int)
void two(int step) //Convert step to binary and save it with array from xyz[1] { int i,j=1; memset(xyz,0,sizeof(xyz)); //Zero xyz i=step; while(i) { xyz[j]=i%2; i/=2; j++; } return; }
int bijiao(void)
int bijiao() //When the steps are the same, when comparing the dictionary order of ans and b, the array dictionary order is small and returns 1 { int i,j,t=1; for(i=1;i<=n;i++) { for(j=1;j<=m;j++) { if(b[i][j]>ans[i][j]) { t=0; break; } } } return t; }
void zuihou(void)
void zuihou() //Obviously, this is a function of covering ans when the step number of b or the dictionary order is small { int i,j; for(i=1;i<=n;i++) { for(j=1;j<=m;j++) { ans[i][j]=b[i][j]; } } return ; }
int baoli(void)
int baoli(void) //Named violence represents the weak tendency of violence { int sum=0; //Steps to save this traversal int i,j,k; for(i=0;i<=pow(2,m)-1;i++) //From 0 to pow (2, m) - 1 to binary is from 00000-111111 { two(i); //switching sites res(); //Reset a array sum=0; memset(b,0,sizeof(b)); //Flip array on zero reset for(j=1;j<=m;j++) //When a bit of binary array is 1, flip the corresponding first row of squares { if(xyz[j]==1) { fan(1,j); //Flip emm b[1][j]=1; //Save flipped box sum++; //Step + + } } for(j=2;j<=n;j++) //Traverse from the second line. When the corresponding block of the previous line is 1, flip the block of this line { for(k=1;k<=m;k++) { if(a[j-1][k]==1) { fan(j,k); b[j][k]=1; sum++; } } } if(panduan()==1) //Judge whether the last line is all white { if(sum<ann) { ann=sum; zuihou(); } else if(ann==sum)//Determine the dictionary order when the steps are equal to the global minimum steps { if(bijiao()) { zuihou(); } } } } if(ann==0x3f3f3f3f) //If none of the conditions are met, return - 1 return -1; else { return 0; } }
Put the ac code last
#include<stdio.h> #include<string.h> #include<math.h> int m,n; int map[20][20],a[20][20],b[20][20],ans[20][20],ann=0x3f3f3f3f; int xyz[20]; int baoli(void); void res(void); void two(int); void fan(int,int); int panduan(void); void zuihou(void); int bijiao(void); int main() { int i,j; scanf("%d %d",&n,&m); for(i=1;i<=n;i++) { for(j=1;j<=m;j++) { scanf("%d",&map[i][j]); } } res(); int p=baoli(); if(p!=-1) { for(i=1;i<=n;i++) { for(j=1;j<=m;j++) { printf("%d ",ans[i][j]); } printf("\n"); } } else { printf("IMPOSSIBLE\n"); } return 0; } int baoli(void) { int sum=0; int i,j,k; for(i=0;i<=pow(2,m)-1;i++) { two(i); res(); sum=0; memset(b,0,sizeof(b)); for(j=1;j<=m;j++) { if(xyz[j]==1) { fan(1,j); b[1][j]=1; sum++; } } for(j=2;j<=n;j++) { for(k=1;k<=m;k++) { if(a[j-1][k]==1) { fan(j,k); b[j][k]=1; sum++; } } } if(panduan()==1) { if(sum<ann) { ann=sum; zuihou(); } else if(ann==sum) { if(bijiao()) { zuihou(); } } } } if(ann==0x3f3f3f3f) return -1; else { return 0; } } int bijiao() { int i,j,t=1; for(i=1;i<=n;i++) { for(j=1;j<=m;j++) { if(b[i][j]>ans[i][j]) { t=0; break; } } } return t; } void zuihou() { int i,j; for(i=1;i<=n;i++) { for(j=1;j<=m;j++) { ans[i][j]=b[i][j]; } } return ; } int panduan(void) { int i,t=1; for(i=1;i<=m;i++) { if(a[n][i]==1) { t=0; break; } } return t; } void two(int step) { int i,j=1; memset(xyz,0,sizeof(xyz)); i=step; while(i) { xyz[j]=i%2; i/=2; j++; } return; } void res(void) { int i,j; for(i=1;i<=n;i++) { for(j=1;j<=m;j++) { a[i][j]=map[i][j]; } } return; } void fan(int x,int y) { a[x][y]=(a[x][y]+1)%2; a[x-1][y]=(a[x-1][y]+1)%2; a[x][y-1]=(a[x][y-1]+1)%2; a[x+1][y]=(a[x+1][y]+1)%2; a[x][y+1]=(a[x][y+1]+1)%2; return; }