BFS:
1。双向广搜
hdu 1401
题意:一个8 x 8的棋盘,上面有4颗棋子,棋子可以上下左右移动。给定一个初始状态和一个目标状态,问能否在8步之内到达。棋子移动有两种方式:
1.将一个棋子移动到一个空的相邻格子中。
2.将一个棋子跳过一个相邻的棋子到一个空的格子中去。
思路:
1.从初始状态开始移动,最多移动4步。
2.从目标状态开始移动,最多移动4步。
3.搜索1时,将每个走到的状态标记为 1 ,每个坐标输入是,我们可以改成是,也就是说只要3个二进制位就可以表示一个横坐标或者纵坐标,6个二进制位就可以存一个棋子的坐标,个二进制位就可以表示一个棋盘的状态,也就是一个型整数就可以存一个棋盘的状态(也就是说 值用就能存),注意在前要先排序,比如(2,3),(2,4),(5,6),(5,7)与(2,4),(5,6),(5,7),(2,3)虽然顺序不同,但都是同一个状态。
4.搜索2时,如果当前状态为 1 ,输出“YES";如果状态 为 0 ,标记为 2;如果状态为 2 ,跳过(其实就是剪枝)。
code:
#include<bits/stdc++.h> using namespace std; int dis[4][2]={0,1,0,-1,1,0,-1,0}; map<int,int> flag; struct zuobiao{ int x,y; bool check(){ if(x>=0 && x<8 && y>=0 && y<8) return false; return true; } bool operator<(const zuobiao&a)const{ return x!=a.x?x<a.x:y<a.y; } }; typedef struct Node{ zuobiao pos[4]; int step; }node; int Hash(zuobiao *a) { int t=0; sort(a,a+4); for (int i=0;i<4;i++) { t|=(a[i].x<<(6*i)); t|=(a[i].y<<(6*i+3)); } return t; } bool judge(int x,int y,zuobiao *a,int v){ for (int k=0;k<4;k++) if (k!=v) { if (a[k].x==x && a[k].y==y) return false; } return true; } bool bfs(int kind,node a) { int t=Hash(a.pos); if(kind==2&&flag[t]==1) return true; flag[t]=kind; queue<node>q; q.push(a); while(!q.empty()){ node u=q.front(); q.pop(); if (u.step>=4) continue; for (int i=0;i<4;i++) for (int j=0;j<4;j++) { node v=u; v.step++; v.pos[i].x+=dis[j][0]; v.pos[i].y+=dis[j][1]; if (v.pos[i].check()) continue; if ( judge(v.pos[i].x, v.pos[i].y, u.pos, i) ) { t=Hash(v.pos); if(kind==1&&flag[t]!=1) { flag[t]=1; q.push(v); } if(kind==2) { if(flag[t]==1) return true; else if(flag[t]!=2) { flag[t]=2; q.push(v); } } } else { v.pos[i].x+=dis[j][0]; v.pos[i].y+=dis[j][1]; if (v.pos[i].check() || !judge(v.pos[i].x, v.pos[i].y, u.pos, i)) continue; t=Hash(v.pos); if(kind==1&&flag[t]!=1) { flag[t]=1; q.push(v); } if(kind==2) { if(flag[t]==1) return true; else if(flag[t]!=2) { flag[t]=2; q.push(v); } } } } } return false; } int main() { node s,e; while( ~scanf("%d%d",&s.pos[0].x,&s.pos[0].y) ) { --s.pos[0].x; --s.pos[0].y; for(int i=1;i<4;++i) { scanf("%d%d",&s.pos[i].x,&s.pos[i].y); --s.pos[i].x,--s.pos[i].y; } for(int i=0;i<4;++i) { scanf("%d%d",&e.pos[i].x,&e.pos[i].y); --e.pos[i].x,--e.pos[i].y; } s.step=0; e.step=0; bfs(1,s); printf("%s\n",bfs(2,e)?"YES":"NO"); flag.clear(); } return 0; }