这里借鉴了Ciel的思想.
//用一个9位的二进制数来表示网格信息,即0表示对应位为白色,1为黑色.
#include <iostream>
#include <string>
#include <queue>
#include <memory.h>
using namespace std;
struct point{
int step;
string s;
point(int step)
{
this->step = step;
this->s = "";
}
point(int step,string s)
{
this->step = step;
this->s = s;
}
};
bool visited[512];//因为九位的二进制数为111111111,等于十进制的511,所以这边最少要取512
int field[10] = {0,432,504,216,438,511,219,54,63,27};//九个动作分别对应的二进制数的表示,如432,就是在区域1也就是网格的1进行了一次操作,则相对于000000000来说第1,2,4,5变成了1,成为110110000等于432.
int changeToBinary(string str)
{
int result = 0;
for(int i = 0;i < 9;i++)
{
result <<= 1;//左移一位
result |= str[i] == 'b' ? 1 : 0;
}
return result;
}
void bfs(int start)
{
queue<point> que;
que.push(point(start));
memset(visited,false,sizeof(visited));
visited[start] = true;
while(!que.empty())
{
point temp = que.front();
que.pop();
if(temp.step == 0)//step等于0表示在上一步中,与一个操作a异或之后为0,即做的一个操作等于操作a,而操作a则是field数组中的一个.即做完操作a就可使所有点为白色
{
cout << temp.s << endl;
return;
}
for(int i = 1;i < 10;i++)
{
int t = temp.step ^ field[i];//按位异或,如果不同则为1,相同为0
if(!visited[t])//判断此操作之前是否做过,因为操作连续做两次的话结果和原来一样,比如1两次以后又变为1
{
visited[t] = true;
string s = temp.s;
s += i + '0';
que.push(point(t,s));
}
}
}
}
int main()
{
int caseNum;
cin >> caseNum;
while(caseNum--)
{
string str;
cin >> str;
int n = changeToBinary(str);//将n当做起始点
if(str == "wwwwwwwww")
cout << 11 << endl;
else
bfs(n);
}
return 0;
}