poj 3279:
Description
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
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
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
下面是ac代码
#include<cstring>
#include<iostream>
#include<cstdio>
using namespace std;
int tu[20][20];
int fanzhuan[20][20];
int best[20][20];
#define INF 0x3f3f3f3f
int time=INF;
int time2=INF;
int dir[4][2]={0,-1,0,0,0,1,-1,0};
int M,N;
int need(int a,int b)
{
int fx,fy,m=tu[a][b];
for(int i=0;i<4;++i)
{
fx=a+dir[i][0];
fy=b+dir[i][1];
if(fx>=1&&fx<=M&&fy>=1&&fy<=N)m+=fanzhuan[fx][fy];
}
return m%2;
}
int solve()
{
int ans=0;
for(int i=2;i<=M;++i)
for(int j=1;j<=N;++j)
if(need(i-1,j)){fanzhuan[i][j]=1;++ans;}
for(int i=1;i<=N;++i)
if(need(M,i))return INF;
for(int i=1;i<=N;++i)
ans+=fanzhuan[1][i];
return ans;
}
int main()
{
scanf("%d%d",&M,&N);
for(int i=1;i<=M;++i)
for(int j=1;j<=N;++j)
scanf("%d",&tu[i][j]);
for(int s=0;s<(1<<N);++s)
{
memset(fanzhuan,0,sizeof(fanzhuan));
for(int i=1;i<=N;++i)
fanzhuan[1][i]=s>>(N-i)&1;
time2=solve();
if(time>time2){time=time2;memcpy(best,fanzhuan,sizeof(fanzhuan));}
}
if(time==INF)printf("IMPOSSIBLE\n");
else
{
for(int i=1;i<=M;++i)
for(int j=1;j<=N;++j)
printf("%d%c",best[i][j],j==N?'\n':' ');
}
return 0;
}
poj 1753:
Description
Flip game is played on a rectangular 4x4 field with two-sided pieces placed on each of its 16 squares. One side of each piece is white and the other one is black and each piece is lying either it's black or white side up. Each round you flip 3 to 5 pieces, thus changing the color of their upper side from black to white and vice versa. The pieces to be flipped are chosen every round according to the following rules:
- Choose any one of the 16 pieces.
- Flip the chosen piece and also all adjacent pieces to the left, to the right, to the top, and to the bottom of the chosen piece (if there are any).
Consider the following position as an example: bwbw wwww bbwb bwwb Here "b" denotes pieces lying their black side up and "w" denotes pieces lying their white side up. If we choose to flip the 1st piece from the 3rd row (this choice is shown at the picture), then the field will become: bwbw bwww wwwb wwwb The goal of the game is to flip either all pieces white side up or all pieces black side up. You are to write a program that will search for the minimum number of rounds needed to achieve this goal.
Input
The input consists of 4 lines with 4 characters "w" or "b" each that denote game field position.
Output
Write to the output file a single integer number - the minimum number of rounds needed to achieve the goal of the game from the given position. If the goal is initially achieved, then write 0. If it's impossible to achieve the goal, then write the word "Impossible" (without quotes).
Sample Input
bwwb bbwb bwwb bwww
Sample Output
4
下面是ac代码
#include<cstring> #include<iostream> #include<cstdio> using namespace std; char tu[20][20]; int tu1[20][20]; int tu2[20][20]; int fanzhuan[20][20]; #define INF 0x3f3f3f3f int time=INF; int time2=INF; int dir[5][2]={0,-1,0,0,0,1,-1,0,1,0}; int M,N; int need(int a,int b,int i) { int fx,fy,m; if(i==1)m=tu1[a][b];else m=tu2[a][b]; for(int i=0;i<5;++i) { fx=a+dir[i][0]; fy=b+dir[i][1]; if(fx>=1&&fx<=4&&fy>=1&&fy<=4)m+=fanzhuan[fx][fy]; } return m%2; } int solve(int x) { int ans=0; for(int i=2;i<=4;++i) for(int j=1;j<=4;++j) if(need(i-1,j,x))fanzhuan[i][j]=1; for(int i=1;i<=4;++i) if(need(4,i,x))return INF; for(int i=1;i<=4;++i) for(int j=1;j<=4;++j) ans+=fanzhuan[i][j]; return ans; } int main() { for(int i=1;i<=4;++i) scanf("%s",&tu[i]); for(int i=1;i<=4;++i) for(int j=1;j<=4;++j) { if(tu[i][j-1]=='b'){tu1[i][j]=1;tu2[i][j]=0;} if(tu[i][j-1]=='w'){tu1[i][j]=0;tu2[i][j]=1;} } for(int s=0;s<(1<<4);++s) { memset(fanzhuan,0,sizeof(fanzhuan)); for(int i=1;i<=4;++i) fanzhuan[1][i]=s>>(4-i)&1; time2=solve(1); if(time>time2)time=time2; memset(fanzhuan,0,sizeof(fanzhuan)); for(int i=1;i<=4;++i) fanzhuan[1][i]=s>>(4-i)&1; time2=solve(0); if(time>time2)time=time2; } if(time==INF)printf("Impossible\n"); else { cout<<time<<endl; } return 0; }
为什么要将这两个题放在一起呢 是因为这两个题的题意相似 同样是翻转一个格子的同时附近的四个格子的颜色也会改变,第一个题要求将一个M*N的矩阵反转成所有的方格都为0,输出在最少的翻转次数的情况下如何翻转(输出翻转矩阵),第二个题是要求将4*4的矩阵反转,要求输出翻转次数,最终结果是全部都变成同样的颜色,全为1或0,第二个题稍微改了改第一个题的代码就提交上去ac了= =,这两个题属于比较少见的搜索题吧 自己体会吧 继续刷题了