廣搜的問題,重點是位運算的應用。每翻轉一個狀態就對應一個16位的二進制數。翻轉一次就是把某個數上下左右四個位置的棋子都翻轉,即0->1,1->0。
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 26891 | Accepted: 11647 |
Description
- 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
Output
Sample Input
bwwb bbwb bwwb bwww
Sample Output
4
#include <stdio.h>
#include <queue>
using namespace std;
queue<int> q;
bool flag[0x10000];
int step[0x10000];
int calculate(int num,int i) //num爲當前狀態對應的數,i爲第幾位
{
int p = 1 << i; //p左移i位
if(i % 4 != 0) //不是最右邊一列
p |= 1 << (i - 1); //翻轉右邊的棋子
if((i + 1) % 4 != 0) //不是最左邊一列
p |= 1 << (i + 1); //翻轉左邊的棋子
if(i > 3) //不是最下邊一行
p |= 1 << (i - 4); //翻轉下邊的棋子
if(i < 12) //不是最上邊一行
p |= 1 << (i + 4); //翻轉上邊的棋子
return num ^ p; //^是按位異或
}
int bfs()
{
while(!q.empty())//隊非空
{
int num = q.front();//對頭元素
q.pop();
int i;
for(i=0; i<16; i++)//循環16次
{
int new_num = calculate(num, i);//下一個狀態
if(flag[new_num] != 1)//未標記過
{
if(new_num == 0 || new_num == 0xffff)//終止條件,即全白或全黑
return step[num] + 1;
q.push(new_num);//進隊
flag[new_num] = 1;//標記
step[new_num] = step[num] + 1;//步數累加
}
}
}
return -1;//未翻到目標狀態,則返回-1
}
int main()
{
char ch;
int num = 0;
int i = 16;
while(i --)
{
scanf("%c",&ch);
if(ch == '\n' || ch == ' ')//遇到換行和空格,不記錄,i相應++
{
i ++;
continue;
}
num <<= 1;//num左移1位
if(ch == 'w')//如果是w,即白色,則num相應位置記爲1
num ++;
}
flag[num] = 1;//當前狀態,標記數組記爲1
q.push(num);
step[num] = 0;
if(num == 0 || num == 0xffff)
{
printf("0\n");
return 0;
}
int t = bfs();
if(t != -1)
printf("%d\n",t);
else
printf("Impossible\n");
return 0;
}
15 | 14 | 13 | 12 |
11 | 10 | 9 | 8 |
7 | 6 | 5 | 4 |
3 | 2 | 1 | 0 |