HDU 1401 双向状态搜索
来源:互联网 发布:清华软件学院排名 编辑:程序博客网 时间:2024/06/06 00:43
第一次写双向状态搜索,输得这么惨,控制不了时间,有很多浪费的时间,不知道如何去控制,代码拍过三遍,最后一遍算是成功的,可是肯定超时,不知道如何优化它。。
只有等以后实力提高了再来搞定它。。
我得理解,每种状态有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 54 4 4 5 5 4 6 54 4 4 5 5 4 6 52 4 3 3 3 6 4 6*/
- HDU 1401 双向状态搜索
- HDU 1401 Solitaire(双向搜索)
- hdu 1401 双向搜索(bfs)
- HDU 1401 Solitaire (双向搜索)
- HDU 1401 Solitaire(双向广度优先搜索)
- HDU 3095 哈希+双向搜索
- hdu 1401 双向广搜+8进制压缩状态
- HDU 4536 状态搜索
- hdu 1429 状态搜索
- HDU 1429 BFS+状态搜索
- hdu 4771 状态压缩搜索
- HDU - 4784(状态设计搜索)
- 搜索+状态压缩 hdu 1429
- hdu 1401 双向bfs
- HDU 1401 双向BFS !!!
- HDU 1885 Key Task 状态压缩+搜索
- HDU 5094(状态压缩搜索)
- hdu 1151 - > 双向路径搜索解决覆盖问题
- 坐标
- TCP/IP-复习笔记(1)UDP
- javax.el.PropertyNotFoundException: Property 'xxx' not found on type
- 检查apache服务器是否正在运行的脚本
- SQL----多张表连接查询,只查出符合条件的数据
- HDU 1401 双向状态搜索
- 数组进行增、删、查、改
- using语句
- 我的VMware认证设计专家(VCDX)之路-经历篇
- SD卡在MTK6577中的架构
- 不懂windows编程,谁能帮帮我啊!!!
- java ArrayList代替数组
- js操作select,增,删,改,查
- 配置操作系统环境