HDU 1401 双向状态搜索
2013-04-10 20:33
417 查看
第一次写双向状态搜索,输得这么惨,控制不了时间,有很多浪费的时间,不知道如何去控制,代码拍过三遍,最后一遍算是成功的,可是肯定超时,不知道如何优化它。。
只有等以后实力提高了再来搞定它。。
我得理解,每种状态有16种后继状态,可是当跳跃到下一步的时候,却写不出o(1)的判断,最后就成16*o(4) = 64;这样写不超时才叫怪事。。。搞了我三天了。。
贴上神牛的代码:
也附上我自己超时的代码:
只有等以后实力提高了再来搞定它。。
我得理解,每种状态有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 */
相关文章推荐
- hdu 1401 Solitaire 双向广度搜索
- HDU 1401 Solitaire(双向搜索)
- hdu 1401 双向搜索(bfs)
- HDU 1401 Solitaire (双向搜索)
- HDU 1429 BFS+状态搜索
- hdu 1151 - > 双向路径搜索解决覆盖问题
- HDU 1401 Solitaire 双向BFS
- HDU-5025 Saving Tang Monk 广度搜索 状态压缩
- hdu 1429 状态搜索
- HDU 4536 状态搜索
- hdu 1151 - > 双向路径搜索解决覆盖问题
- HDU 1495 非常可乐!!!(隐式图状态搜索+bfs+map状态查重)
- HDU 3095 哈希+双向搜索
- HDU 5094(状态压缩搜索)
- HDU_1401——分步双向BFS,八进制位运算压缩,map存放hash
- hdu 1151 - > 双向路径搜索解决覆盖问题
- HDU 6171 Admiral 双向搜索(meet in the middle) + 哈希
- hdu4845 状态压缩搜索水题
- HDU 1401 Solitaire 双向BFS
- uva 1601 poj 3523 Morning after holloween 万圣节后的早晨 (经典搜索,双向bfs+预处理优化+状态压缩位运算)