您的位置:首页 > 大数据 > 人工智能

hdu1401 Solitaire【双广】

2012-11-24 17:39 363 查看
#include<cstdio>
#include<cstring>
#include<set>
#include<queue>
#include<algorithm>
using namespace std;

const int dx[4]={-1,0,1,0};
const int dy[4]={0,-1,0,1};

struct node
{
int x[4],y[4];
}sn,en,tmp;
queue<node> Q[2];
set<int> S[2];
bool flag;

int ok(node &cur,int k,int d)
{
if( cur.x[k]<1 || cur.x[k]>8 || cur.y[k]<1 || cur.y[k]>8 )  return 0;
bool flag=false;
for(int i=0;i<4;i++)
if( i!=k && cur.x[k]==cur.x[i] && cur.y[k]==cur.y[i] ){flag=true;break;}
if( !flag ) return 1;
int nx=cur.x[k]+dx[d],ny=cur.y[k]+dy[d];
if( nx<1 || nx>8 || ny<1 || ny>8 )  return 0;
for(int i=0;i<4;i++)
if( nx==cur.x[i] && ny==cur.y[i] )  return 0;
return 2;
}

bool cmp(int a,int b)
{
if( tmp.x[a]!=tmp.x[b] )    return tmp.x[a]<tmp.x[b];
else return tmp.y[a]<tmp.y[b];
}

int hash(node &cur)
{
int id[4]={0,1,2,3},code=0;

tmp=cur;
sort(id,id+4,cmp);
for(int i=0;i<4;i++)    code=code*8+cur.x[id[i]]-1;
for(int i=0;i<4;i++)    code=code*8+cur.y[id[i]]-1;
return code;
}

void bfs(int d)
{
int size=Q[d].size();
while( size-- )
{
node cur=Q[d].front();

Q[d].pop();
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
{
node next=cur;
int sel,code;

next.x[i]+=dx[j];
next.y[i]+=dy[j];
sel=ok(next,i,j);
if( !sel )  continue;
else if( 2==sel )  next.x[i]+=dx[j],next.y[i]+=dy[j];
code=hash(next);
if( S[d].find(code)!=S[d].end() )   continue;
if( S[d^1].find(code)!=S[d^1].end() )   {flag=true;return;}
S[d].insert(code);
Q[d].push(next);
}
}
}

bool dbfs(void)
{
int code1,code2,cnt=0;

flag=false;
S[0].clear();
S[1].clear();
while( !Q[0].empty() )  Q[0].pop();
while( !Q[1].empty() )  Q[1].pop();
code1=hash(sn);
code2=hash(en);
if( code1==code2 )  return true;
S[0].insert(code1);
Q[0].push(sn);
S[1].insert(code2);
Q[1].push(en);
while( ++cnt<=8 )
{
if( Q[0].size()<Q[1].size() )   bfs(0);
else bfs(1);
if( flag )  return flag;
}
return false;
}

int main()
{
while( true )
{
for(int i=0;i<4;i++)    if( scanf("%d%d",&sn.x[i],&sn.y[i])==EOF )  return 0;
for(int i=0;i<4;i++)    scanf("%d%d",&en.x[i],&en.y[i]);
puts(dbfs()?"YES":"NO");
}
}
/*
第一道双广
普通bfs的最坏复杂度是C(64,4)=635376
由于每一个当前状态可以拓展出16个新状态,从起点和终点出发,每边最多拓展4层
那么双广的最坏复杂度2*16^4=2*17=131072
*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: