题目大意:
跳棋,8*8的棋盘,上有4个棋子,给你一个初始状态给你一个结束状态,问能不能在8步之内从初始状态走到结束状态。
解题思路:
双向BFS问题
代码如下:
#include<cstdio>
#include<queue>
#include<set>
#include<string.h>
#include<algorithm>
using namespace std;
int map[9][9],a[9];
int dirx1[4]={0,0,1,-1};
int diry1[4]={1,-1,0,0};
int dirx2[4]={0,0,2,-2};
int diry2[4]={2,-2,0,0};
struct state
{
int pos,cnt;
};
bool check(int r,int c)
{
if(r<=8&&r>=1&&c<=8&&c>=1)
return true;
return false;
}
void getmap(int pos)
{
memset(map,0,sizeof(map));
while(pos)
{
int c=pos%10;
pos/=10;
int r=pos%10;
pos/=10;
map[r][c]=1;
}
}
int getpos()
{
int r=0;
for(int i=1;i<=8;i++)
{
for(int j=1;j<=8;j++)
{
if(map[i][j])
{
r=r*10+i;
r=r*10+j;
}
}
}
return r;
}
bool bfs(int start,int end)
{
set<int>close;
close.insert(start);
queue<state>q;
state o;
o.pos=start;
o.cnt=0;
q.push(o);
int x,y;
while(!q.empty())
{
state t=q.front();
q.pop();
getmap(t.pos);
++t.cnt;
for(int i=1;i<=8;i++)
{
for(int j=1;j<=8;++j)
{
if(map[i][j])
{
for(int d=0;d<4;d++)
{
x=i+dirx1[d];
y=j+diry1[d];
if(check(x,y)&&!map[x][y])
{
map[i][j]=0;
map[x][y]=1;
int pt=getpos();
if(close.find(pt)==close.end())
{
close.insert(pt);
if(pt==end)
return true;
if(t.cnt<8)
{
t.pos=pt;
q.push(t);
}
}
map[i][j]=1;
map[x][y]=0;
}
x=i+dirx2[d];
y=j+diry2[d];
if(check(x,y)&&!map[x][y]&&
map[i+dirx1[d]][j+diry1[d]])
{
map[i][j]=0;
map[x][y]=1;
int pt=getpos();
if(close.find(pt)==close.end())
{
close.insert(pt);
if(pt==end)
return true;
if(t.cnt<8)
{
t.pos=pt;
q.push(t);
}
}
map[i][j]=1;
map[x][y]=0;
}
}
}
}
}
}
return false;
}
bool dbfs(int start,int end)
{
set<int>close1;
set<int>close2;
close1.insert(start);
close2.insert(end);
queue<state>q1;
queue<state>q2;
state t1;
t1.pos=start;
t1.cnt=0;
q1.push(t1);
t1.pos=end;
q2.push(t1);
int x,y;
int n1=0;
int m1=1;
int n2=0;
int m2=1;
while(!q1.empty()||!q2.empty())
{
n1=m1;
m1=0;
n2=m2;
m2=0;
while(n1--)
{
state t=q1.front();
q1.pop();
getmap(t.pos);
++t.cnt;
for(int i=1;i<=8;i++)
{
for(int j=1;j<=8;j++)
{
if(map[i][j])
{
for(int d=0;d<4;d++)
{
x=i+dirx1[d];
y=j+diry1[d];
if(check(x,y)&&!map[x][y])
{
map[i][j]=0;
map[x][y]=1;
int pt=getpos();
if(close2.find(pt)!=close2.end())
return true;
if(close1.find(pt)==close1.end())
{
close1.insert(pt);
if(pt==end)
return true;
if(t.cnt<4)
{
t.pos=pt;
q1.push(t);
++m1;
}
}
map[i][j]=1;
map[x][y]=0;
}
x=i+dirx2[d];
y=j+diry2[d];
if(check(x,y)&&!map[x][y]&&
map[i+dirx1[d]][j+diry1[d]])
{
map[i][j]=0;
map[x][y]=1;
int pt=getpos();
if(close2.find(pt)!=
close2.end())
return true;
if(close1.find(pt)==
close1.end())
{
close1.insert(pt);
if(pt==end)
return true;
if(t.cnt<4)
{
t.pos=pt;
q1.push(t);
++m1;
}
}
map[i][j]=1;
map[x][y]=0;
}
}
}
}
}
}
while(n2--)
{
state t=q2.front();
q2.pop();
getmap(t.pos);
++t.cnt;
for(int i=1;i<=8;i++)
{
for(int j=1;j<=8;j++)
{
if(map[i][j])
{
for(int d=0;d<4;d++)
{
x=i+dirx1[d];
y=j+diry1[d];
if(check(x,y)&&!map[x][y])
{
map[i][j]=0;
map[x][y]=1;
int pt=getpos();
if(close1.find(pt)!=close1.end())
return true;
if(close2.find(pt)==close2.end())
{
close2.insert(pt);
if(pt==end)
return true;
if(t.cnt<4)
{
t.pos=pt;
q2.push(t);
++m2;
}
}
map[i][j]=1;
map[x][y]=0;
}
x=i+dirx2[d];
y=j+diry2[d];
if(check(x,y)&&!map[x][y]&&
map[i+dirx1[d]][j+diry1[d]])
{
map[i][j]=0;
map[x][y]=1;
int pt=getpos();
if(close1.find(pt)!=
close1.end())
return true;
if(close2.find(pt)==
close2.end())
{
close2.insert(pt);
if(pt==end)
return true;
if(t.cnt<4)
{
t.pos=pt;
q2.push(t);
++m2;
}
}
map[i][j]=1;
map[x][y]=0;
}
}
}
}
}
}
}
return false;
}
int main()
{
while(scanf("%d%d%d%d%d%d%d%d",
&a[1],&a[2],&a[3],&a[4],&a[5],&a[6],
&a[7],&a[8])!=EOF)
{
memset(map,0,sizeof(map));
map[a[1]][a[2]]=1;
map[a[3]][a[4]]=1;
map[a[5]][a[6]]=1;
map[a[7]][a[8]]=1;
int start=getpos();
scanf("%d%d%d%d%d%d%d%d",
&a[1],&a[2],&a[3],&a[4],&a[5],&a[6],
&a[7],&a[8]);
memset(map,0,sizeof(map));
map[a[1]][a[2]]=1;
map[a[3]][a[4]]=1;
map[a[5]][a[6]]=1;
map[a[7]][a[8]]=1;
int end=getpos();
if(start==end)
{
printf("YES\n");
continue;
}
if(dbfs(start,end))
printf("YES\n");
else
printf("NO\n");
}
return 0;
}
6339

被折叠的 条评论
为什么被折叠?



