OPJ2.5基本算法之搜索200:Solitaire
题目传送门
看网上的题解有点少,我就来水 写一篇博客,给有需要的宝宝们
思路:八维数组!同时搜四个点!干就完了!虽然OPJ的数据水,但还是要有一些阴间卡内存的,具体看代码。
AC代码:
#include<bits/stdc++.h>
using namespace std;
bool vis[8][8][8][8][8][8][8][8];
int g[10][10];
int fx[][2]={1,0,-1,0,0,1,0,-1};
struct node
{
int x[4],y[4];
int step;
}s,e;
bool check(node a)
{
for(int i=0;i<4;i++)
if(!g[a.x[i]][a.y[i]])return 0;
return 1;
}
bool judge(node a)
{
for(int i=0;i<4;i++)
if(a.x[i]<0||a.x[i]>=8||a.y[i]<0||a.y[i]>=8)return 1;
if(vis[a.x[0]][a.y[0]][a.x[1]][a.y[1]][a.x[2]][a.y[2]][a.x[3]][a.y[3]])return 1;
return 0;
}
bool empty(node a, int k)
{
for(int i=0;i<4;i++)
if(i!=k&&a.x[i]==a.x[k]&&a.y[i]==a.y[k])return 0;
return 1;
}
bool bfs()
{
memset(vis, 0, sizeof vis);
queue<node>q;
node a,b;
a.step=0;
for(int i=0;i<4;i++)
{
a.x[i]=s.x[i];
a.y[i]=s.y[i];
}
q.push(a);
vis[a.x[0]][a.y[0]][a.x[1]][a.y[1]][a.x[2]][a.y[2]][a.x[3]][a.y[3]]=1;
while(!q.empty())
{
a=q.front();q.pop();
if(a.step>=8)return 0;
if(check(a))return 1;
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
{
b=a;
b.x[i]+=fx[j][0];b.y[i]+=fx[j][1];
b.step++;
if(judge(b))continue;
if(empty(b,i))
{
if(check(b))return 1;
vis[b.x[0]][b.y[0]][b.x[1]][b.y[1]][b.x[2]][b.y[2]][b.x[3]][b.y[3]]=1;
q.push(b);
}
else
{
b.x[i]+=fx[j][0];b.y[i]+=fx[j][1];
if(judge(b)||!empty(b,i))continue;
if(check(b))return 1;
vis[b.x[0]][b.y[0]][b.x[1]][b.y[1]][b.x[2]][b.y[2]][b.x[3]][b.y[3]]=1;
q.push(b);
}
}
}
return 0;
}
int main()
{
while(cin>>s.x[0]>>s.y[0])
{
s.x[0]--;s.y[0]--;//卡内存*1
for(int i=1;i<4;i++)
{
cin>>s.x[i]>>s.y[i];
s.x[i]--;s.y[i]--;卡内存*2
}
memset(g,0,sizeof g);
for(int i=0;i<4;i++)
{
cin>>e.x[i]>>e.y[i];
e.x[i]--;e.y[i]--;卡内存*3
g[e.x[i]][e.y[i]]=1;
}
bool flag=bfs();
if(flag)cout <<"YES"<<endl;
else cout<<"NO"<<endl;
}
return 0;
}