拿到这个题目时,觉得无从下手,觉得这怎么写啊,完全没头绪
后来百度之,发现了别人的一些分析,可是还是没怎么看的懂,下午出去转转之后,忽然理解了,就记下来
先将b,w的字符串对应二进制数1,0, 那么当输入都是w时,对应的十进制数就是0了
程序中先行保存每一个节点影响数(十进制保存),影响到的节点标记1,不影响的标记0,然后将这个9位的二进制转化为十进制数,即影响数
那么当整个棋谱处于一个状态时,此状态对应一个整数,这个整数与任意一个节点的影响数进行异或操作就相当于翻一次那个节点,那个节点影响到的节点也会改变
整个棋谱一共有9个位置,每个2中状态,所以棋谱一共只有2^9 = 512种不同状态,使用广度优先的搜索方法,直到某一次的当前状态就是我们想要的状态(0)即停止
#include <iostream>
#include <string>
#include <string.h>
#include <queue>
#include <vector>
#include <stdio.h>
#include <math.h>
#include <list>
#include <stack>
#include <set>
#include <map>
#include <algorithm>
using namespace std;
char input[10];
int neighbour[10] = {0,432,504,216,438,511,219,54,63,27};
const int MAX = 600; //大于512即可
bool visited[MAX];
struct Node
{
int value;
string road;
Node(int v , string s)
{
value = v;
road = s;
}
Node(int v)
{
value = v;
road = "";
}
};
int chartoint() //将输入的状态转化为整数
{
int res = 0;
for(int i=0;i<9;i++)
{
res = res * 2;
if(input[i] == 'b')
res += 1;
}
return res;
}
void bfs(int a)
{
for(int i=0;i<MAX;i++)
visited[i] = false;
queue<Node> qu;
qu.push(Node(a));
visited[a] = true;
while(!qu.empty())
{
Node temp = qu.front();
qu.pop();
if(temp.value == 0) //全部都是白色时的对应的字符串,转化为十进制是0
{
cout << temp.road << endl;
break;
}
for(int i=1;i<=9;i++)
{
int t = temp.value ^ neighbour[i]; //此操作相当于翻一次i对应的牌
if(!visited[t])
{
visited[t] = true;
string s = temp.road;
s += '0'+i;
qu.push(Node(t,s));
}
}
}
}
int main()
{
int n;
cin>>n;
while(n>0)
{
cin >> input;
int start = chartoint();
if(start == 0) //这个是参考的别人的,具体为啥我也不清楚,应该是他们多次WA之后得出的
cout<<"11"<<endl;
else
bfs(start);
n--;
}
}