二进制+(BFS)暴力枚举
原本用二位字符数组存 发现遍历困难 并且翻动棋子也难办 后来想到一维线性
下标 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
在图中即为
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
预处理出一个数组进行翻转 后来又发现预处理难办 灵光一现 由于只有黑白两色 可用1 0标记 看到1 0想到的当然就是二进制了 并且又做成了个线性 刚好16位二进制 一切迎刃而解 翻转可用二进制运算^(异或) 上代码
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <queue>
#define INF 0x3f3f3f3f
using namespace std;
int ms;
int step[65536];
int dir[32];
bool vis[65536];
int tp;
int GetNum(char *str)//黑1 白 0
{
int i,x = 0;
for(i = 1; i <= 16; ++i)
{
x <<= 1;
x += (str[i] == ‘b‘)? 1: 0;
}
return x;
}
//void PrintNum(int x)
//{
// int i = 1;
// while(x)
// {
// if(x&1) printf("1 ");
// else printf("0 ");
// x >>= 1;
// if(!(i%4)) printf("\n");
// ++i;
// }
// for(; i <= 16; ++i)
// {
// printf("0 ");
// if(!(i%4)) printf("\n");
// }
// printf("\n\n");
//}
void Memset(char *str,char a)
{
int i,j;
for(i = 1; i <= 16; ++i)
str[i] = a;
}
void Getdir()
{
tp = 0;
char str[49];
int i,j;
Memset(str,‘w‘);
for(i = 16; i >= 1; --i)
{
str[i+1] = str[i+5] = str[i+2]= ‘w‘;
if(i-3 > 0) str[i-3] = ‘w‘;
str[i] = str[i+4] = ‘b‘;
if(i%4) str[i+1] = ‘b‘;
if((i-1)%4) str[i-1] = ‘b‘;
if(i-4 > 0) str[i-4] = ‘b‘;
dir[tp++] = GetNum(str);
}
}
void Bfs()
{
memset(step,INF,sizeof(step));
memset(vis,0,sizeof(vis));
step[ms] = 0;
int i,x,v;
queue <int> q;
q.push(ms);
while(!q.empty())
{
x = q.front();
q.pop();
vis[x] = 0;
for(i = 0; i < tp; ++i)
{
v = x^dir[i];
if(step[v] > step[x]+1)
{
step[v] = step[x]+1;
if(!vis[v])
{
q.push(v);
vis[v] = 1;
}
}
}
}
}
int main()
{
//freopen("in.txt","r",stdin);
char str[18];
int i,j,x;
for(i = 1; i < 17; i += 4)
{
scanf("%s",str+i);
}
ms = GetNum(str);
Getdir();
// for(i = 0; i < tp; ++i)
// PrintNum(dir[i]);
if(ms == 0 || ms == 65535) printf("0\n");
else
{
Bfs();
x = min(step[0],step[65535]);
if(x == INF) printf("Impossible\n");
else printf("%d\n",x);
}
return 0;
}
原文地址:http://blog.csdn.net/challengerrumble/article/details/46421079