Flip Game
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 4863 Accepted: 1983
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
Source
Northeastern Europe 2000
大意:翻转棋,每次必须翻转相邻的所有和本身棋子,也就是说如果存在就是上下左右本身,棋盘4*4,全白全黑都算赢
输入:初始状态,4*4行
输出:单行输出需要多少步,如果无解是“Impossible”
#include <cstdio> using namespace std; int vis[65536];//就一组数据所以不初始化 int heap[65536];//16<32,用int和0,1存储整个棋盘 int index;//heap里存了多少组数据 int inver(int l,int i,int j){ int t=l; if(i)l^=1<<(19-j-4*i);//按照左上角i=j=0; if(i!=3)l^=1<<(11-j-4*i); if(j)l^=1<<(16-i*4-j); if(j!=3)l^=1<<(14-i*4-j); l^=1<<(15-i*4-j); if(vis[l]==0){ vis[l]=vis[t]+1; heap[index++]=l; } return l;//没用上 } int bfs(){ for(int k=0;k<index;k++){ if(heap[k]==0||heap[k]==65535)return vis[heap[k]];/*这题输入数据少*/ for(int i=0;i<4;i++){/*错误思路,循环顺序i,j,k,如果是对每一个翻转位置都尝试所有状态, 那么可能在翻转到某个位置之前,输出非最小步数*/ for(int j=0;j<4;j++){ inver(heap[k],i,j); } } } return -1; } int main(){ int l=0; char ch; for(int i=0;i<4;i++){ for(int j=0;j<4;j++){ ch=getchar(); if(ch=='b')l^=1<<(15-4*i-j);//输入数据小,直接翻转 } getchar(); } vis[l]=1; heap[index++]=l; int ans=bfs()-1;//为了区别有无填充,vis[i]=1,但实际翻转次数为0 if(ans>-1)printf("%d\n",ans); else printf("Impossible\n"); return 0; }