您的位置:首页 > 其它

HDU 1401 双向状态搜索

2013-04-10 20:33 417 查看
第一次写双向状态搜索,输得这么惨,控制不了时间,有很多浪费的时间,不知道如何去控制,代码拍过三遍,最后一遍算是成功的,可是肯定超时,不知道如何优化它。。

只有等以后实力提高了再来搞定它。。

我得理解,每种状态有16种后继状态,可是当跳跃到下一步的时候,却写不出o(1)的判断,最后就成16*o(4) = 64;这样写不超时才叫怪事。。。搞了我三天了。。

贴上神牛的代码:

#pragma warning (disable:4786)
#include<stdio.h>
#include<queue>
#include<map>
using namespace std;
typedef struct p{
int x,y;
}Point;
//共有四颗棋子,棋盘大小为64,采用位棋盘表示
typedef struct Map{
unsigned __int64 value;
Point p[4];
int steps,which;
void getvalue()
{//棋盘对应键值
value=0;
for(short i=0;i<4;i++)
value+=(unsigned __int64)1<<((p[i].x-1)*8+(p[i].y-1));
}
}Map;
struct Cmp{
bool operator () (const Map &a,const Map &b) const
{
return a.value<b.value;
}
};
map<Map,int,Cmp>m;
queue<Map>q;
Map start,end;
int dir[][2]={{0,1},{0,-1},{1,0},{-1,0}};

bool Next(Map cur,Map &next,int ith,int d)
{//获取第ith个棋子d方向上的下一个棋面状态
int i,j;

next.p[ith].x=cur.p[ith].x+dir[d][0];
next.p[ith].y=cur.p[ith].y+dir[d][1];

if(next.p[ith].x<1||next.p[ith].x>8||next.p[ith].y<1||next.p[ith].y>8)
return false;
for(i=1;i<4;i++){
if(next.p[ith].x==cur.p[(ith+i)%4].x&&next.p[ith].y==cur.p[(ith+i)%4].y){
next.p[ith].x+=dir[d][0];
next.p[ith].y+=dir[d][1];
if(next.p[ith].x<1||next.p[ith].x>8||next.p[ith].y<1||next.p[ith].y>8)
return false;
for(j=1;j<4;j++){
if(next.p[ith].x==cur.p[(ith+j)%4].x
&&next.p[ith].y==cur.p[(ith+j)%4].y)
return false;
}
return true;
}
}
return true;
}
bool bfs()
{//双向搜索
Map cur,next;
int i,d,k,v;
m.clear();
while(!q.empty()) q.pop();
start.steps=end.steps=0;
start.which=1;end.which=2;
start.getvalue();end.getvalue();
m[start]=1;m[end]=2;
q.push(start);q.push(end);

while(!q.empty()){
cur=q.front(); q.pop();
v=m[cur];
if(cur.steps>4)	break;
if(v!=0&&v!=cur.which)	return true;
for(i=0;i<4;i++){//每一颗棋子
for(d=0;d<4;d++){//每一个方向
if(Next(cur,next,i,d)){
for(k=1;k<4;k++)
next.p[(i+k)%4]=cur.p[(i+k)%4];
next.steps=cur.steps+1;
next.which=cur.which;
next.getvalue();
if(next.steps>4) continue;
v=m[next];
if(v==next.which) continue;
if(v&&v!=next.which) return true;
m[next]=next.which;
q.push(next);
}
}
}
}
return false;
}
int main()
{
int i;
while(1){
for(i=0;i<4;i++){
if(scanf("%d%d",&start.p[i].x,&start.p[i].y)==EOF)
return 0;
}
for(i=0;i<4;i++)
scanf("%d%d",&end.p[i].x,&end.p[i].y);
printf(bfs()?"YES/n":"NO/n");
}
return 0;
}


也附上我自己超时的代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
using namespace std;

struct node {
int x[4],y[4];
};
queue<node>que;
int temp[8][8][8][8][8][8][8][8];
int s[8][8][8][8][8][8][8][8];
int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};

void init(){
while(!que.empty()) que.pop();
memset(temp,0,sizeof(temp));
memset(s,0,sizeof(s));
}

int judge(node te){
if(s[te.x[0]][te.y[0]][te.x[1]][te.y[1]][te.x[2]][te.y[2]][te.x[3]][te.y[3]]>=6){
if(temp[te.x[0]][te.y[0]][te.x[1]][te.y[1]][te.x[2]][te.y[2]][te.x[3]][te.y[3]]>8){
cout<<"NO"<<endl;
return 1;
}
else { cout<<"YES"<<endl; return 1; }
}
if(temp[te.x[0]][te.y[0]][te.x[1]][te.y[1]][te.x[2]][te.y[2]][te.x[3]][te.y[3]]>4) {
cout<<"NO"<<endl; return 1;
}
return 0;
}

int fan(node te){
for(int i=0;i<4;i++){ ////枚举每个棋子
for(int j=0;j<4;j++){ ////枚举四个方向
node p=te;
p.x[i] += dir[j][0];
p.y[i] += dir[j][1];
if(p.x[i]<0 || p.y[i]>=8) continue;
int flag=0;
for(int r=0;r<4;r++){////判断是否有棋子和它重合????超时根源
if(p.x[i]==p.x[r] && p.y[i]==p.y[r] && i!=r){
p.x[i]+=dir[j][0];////再向前移一个位置
p.y[i]+=dir[j][1];
if(p.x[i]<0 || p.y[i]>=8){ flag=1; break; }
for(int k=0;k<4;k++) ///判断是否还有棋子和它重合  ????超时根源
if(p.x[i]==p.x[k] && p.y[i]==p.y[k] && i!=k) flag=1;
if(flag) break;
if(s[te.x[0]][te.y[0]][te.x[1]][te.y[1]][te.x[2]][te.y[2]][te.x[3]][te.y[3]]///状态重合了
==s[p.x[0]][p.y[0]][p.x[1]][p.y[1]][p.x[2]][p.y[2]][p.x[3]][p.y[3]]) {
flag=1; break;
}
if(!s[p.x[0]][p.y[0]][p.x[1]][p.y[1]][p.x[2]][p.y[2]][p.x[3]][p.y[3]]){///状态没有重合
s[p.x[0]][p.y[0]][p.x[1]][p.y[1]][p.x[2]][p.y[2]][p.x[3]][p.y[3]]= ////标记传递
s[te.x[0]][te.y[0]][te.x[1]][te.y[1]][te.x[2]][te.y[2]][te.x[3]][te.y[3]];
temp[p.x[0]][p.y[0]][p.x[1]][p.y[1]][p.x[2]][p.y[2]][p.x[3]][p.y[3]]=////步数叠加
temp[te.x[0]][te.y[0]][te.x[1]][te.y[1]][te.x[2]][te.y[2]][te.x[3]][te.y[3]]+1;
int ss = judge(p);
if(ss) return 1;
que.push(p);
flag=1; break;
}
if(s[te.x[0]][te.y[0]][te.x[1]][te.y[1]][te.x[2]][te.y[2]][te.x[3]][te.y[3]]///状态不同
!=s[p.x[0]][p.y[0]][p.x[1]][p.y[1]][p.x[2]][p.y[2]][p.x[3]][p.y[3]]) {
s[p.x[0]][p.y[0]][p.x[1]][p.y[1]][p.x[2]][p.y[2]][p.x[3]][p.y[3]] *=
s[te.x[0]][te.y[0]][te.x[1]][te.y[1]][te.x[2]][te.y[2]][te.x[3]][te.y[3]];
temp[p.x[0]][p.y[0]][p.x[1]][p.y[1]][p.x[2]][p.y[2]][p.x[3]][p.y[3]]=////步数叠加
temp[te.x[0]][te.y[0]][te.x[1]][te.y[1]][te.x[2]][te.y[2]][te.x[3]][te.y[3]]+1;
int ss = judge(p);
if(ss) return 1;
flag=1; break;
}
}
}
if(flag) continue;
if(s[te.x[0]][te.y[0]][te.x[1]][te.y[1]][te.x[2]][te.y[2]][te.x[3]][te.y[3]]///状态重合了
==s[p.x[0]][p.y[0]][p.x[1]][p.y[1]][p.x[2]][p.y[2]][p.x[3]][p.y[3]]) {
continue;
}
if(!s[p.x[0]][p.y[0]][p.x[1]][p.y[1]][p.x[2]][p.y[2]][p.x[3]][p.y[3]]){///状态没有重合
s[p.x[0]][p.y[0]][p.x[1]][p.y[1]][p.x[2]][p.y[2]][p.x[3]][p.y[3]]= ////标记传递
s[te.x[0]][te.y[0]][te.x[1]][te.y[1]][te.x[2]][te.y[2]][te.x[3]][te.y[3]];
temp[p.x[0]][p.y[0]][p.x[1]][p.y[1]][p.x[2]][p.y[2]][p.x[3]][p.y[3]]=////步数叠加
temp[te.x[0]][te.y[0]][te.x[1]][te.y[1]][te.x[2]][te.y[2]][te.x[3]][te.y[3]]+1;
int ss = judge(p);
if(ss) return 1;
que.push(p);
continue;
}
if(s[te.x[0]][te.y[0]][te.x[1]][te.y[1]][te.x[2]][te.y[2]][te.x[3]][te.y[3]]///状态不同
!=s[p.x[0]][p.y[0]][p.x[1]][p.y[1]][p.x[2]][p.y[2]][p.x[3]][p.y[3]]) {
s[p.x[0]][p.y[0]][p.x[1]][p.y[1]][p.x[2]][p.y[2]][p.x[3]][p.y[3]] *=
s[te.x[0]][te.y[0]][te.x[1]][te.y[1]][te.x[2]][te.y[2]][te.x[3]][te.y[3]];
temp[p.x[0]][p.y[0]][p.x[1]][p.y[1]][p.x[2]][p.y[2]][p.x[3]][p.y[3]]=////步数叠加
temp[te.x[0]][te.y[0]][te.x[1]][te.y[1]][te.x[2]][te.y[2]][te.x[3]][te.y[3]]+1;
int ss = judge(p);
if(ss) return 1;
continue;
}
}
}
return 0;
}

void BFS(){
while(!que.empty()){
node te=que.front();
que.pop();
if(judge(te)) break;
int flag = fan(te);
if(flag) break;
}
}

int main(){
int x[4],y[4],a[4],b[4];
while(cin>>x[0]>>y[0]>>x[1]>>y[1]>>x[2]>>y[2]>>x[3]>>y[3]){
for(int i=0;i<4;i++)
cin>>a[i]>>b[i];
for(int i=0;i<4;i++)
x[i]--,y[i]--,a[i]--,b[i]--;
init();
temp[x[0]][y[0]][x[1]][y[1]][x[2]][y[2]][x[3]][y[3]]=1;
temp[a[0]][b[0]][a[1]][b[1]][a[2]][b[2]][a[3]][b[3]]=1;
s[x[0]][y[0]][x[1]][y[1]][x[2]][y[2]][x[3]][y[3]]=2;/////第一个元素
if(!s[a[0]][b[0]][a[1]][b[1]][a[2]][b[2]][a[3]][b[3]])////处理标记
s[a[0]][b[0]][a[1]][b[1]][a[2]][b[2]][a[3]][b[3]]=3;
else s[a[0]][b[0]][a[1]][b[1]][a[2]][b[2]][a[3]][b[3]]*=3;
node te;
for(int i=0;i<4;i++){
te.x[i]=x[i];
te.y[i]=y[i];
}
que.push(te);
for(int i=0;i<4;i++){
te.x[i]=a[i];
te.y[i]=b[i];
}
que.push(te);
BFS();
}
}
/*

4 4 4 5 5 4 6 5
4 4 4 5 5 4 6 5

4 4 4 5 5 4 6 5
2 4 3 3 3 6 4 6

*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: