J - Flip Game
POJ - 1753
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
題意:好題,翻棋子,每次翻一個棋子左右和上下相鄰的棋子,黑白轉換,求使所有棋子同樣顏色,最少翻幾次
解法:寬搜,類似CUC-SUMMER-2-E,對起始狀態的分別對每一個棋子進行翻轉,記錄翻轉后狀態并存入隊列,存之前要判斷翻轉后狀態之前是否標記過,如果標記過證明一定有更少的翻轉次數達到此狀態,所以返回,直到棋子顏色一致,或能到達的所有狀態都已經達到。存儲棋子狀態用二進制,因為只有黑白兩種情況,與1抑或則翻轉,與0抑或不變。
代碼:
#include<iostream>
#include<queue>
using namespace std;
typedef long long ll;
#define maxn 65535
struct node{
int step;
int visit;
};
node Node[maxn+1];
int start=0;
queue<int> q;
int ans=-1;
bool check(int i,int j){
if(i<0||i>3)
return false;
if(j<0||j>3)
return false;
return true;
}
int BFS()
{
while(!q.empty()){
node now;
int temp=q.front();
now=Node[temp];
q.pop();
if(temp==0||temp==maxn)
return now.step;
for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
int loc=i*4+j;
int next=temp;
next^=1<<(15-loc);
if(check(i,j+1))
next^=1<<(15-(loc+1));
if(check(i,j-1))
next^=1<<(15-(loc-1));
if(check(i-1,j))
next^=1<<(15-(loc-4));
if(check(i+1,j))
next^=1<<(15-(loc+4));
if(Node[next].visit==0){
q.push(next);
Node[next].visit=1;
Node[next].step=now.step+1;
}
}
}
}
return ans;
}
int main()
{
for(int i=0;i<=maxn;i++){
Node[i].step=0;
Node[i].visit=0;
}
char c;
for(int i=0;i<16;i++){
cin>>c;
start*=2;
if(c=='b')
start++;
}
Node[start].visit=1;
q.push(start);
ans=BFS();
if(ans==-1)
cout<<"Impossible"<<endl;
else
cout<<ans<<endl;
}