参考的转载的那一篇文章,写的自己的程序。枚举的经典题,每个点都指向16个其他的点,层序遍历,记录每个点在第几层被遍历到即可。
要注意位操作的简洁和抽象成图的遍历。要从翻面联想到位运算。
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <queue>
using namespace std;
int flipPosition(int id,int position)
{
id ^= (1 << position);
if(position - 4 >= 0)
id ^= (1 << position - 4);
if(position + 4 <= 15)
id ^= (1 << position + 4);
if(position % 4 != 0)
id ^= (1 << position - 1);
if(position % 4 != 3)
id ^= (1 << position + 1);
return id;
}
int main()
{
char c;
int id = 0;
for(int i = 0;i < 16;i++)
{
scanf("%c",&c);
if(c == '\n')
scanf("%c",&c);
int newSite;
if(c == 'b')
newSite = 1;
else
newSite = 0;
id += (newSite << i);
}
if((id == 0) || (id == 65535))
{
printf("0");
return 0;
}
int state[65536];
memset(state,-1,sizeof(state));
state[id] = 0;
queue<int> ids;
ids.push(id);
while(!ids.empty())
{
int nowId = ids.front();
ids.pop();
for(int i = 0;i < 16;i++)
{
int nextId = flipPosition(nowId,i);
if((nextId == 0) || (nextId == 65535))
{
printf("%d",state[nowId] + 1);
return 0;
}
if(state[nextId] == -1)
{
state[nextId] = state[nowId] + 1;
ids.push(nextId);
}
}
}
printf("Impossible");
return 0;
}