HDU - 1401 Solitaire
2017-07-22 17:43
375 查看
Solitaire
Problem DescriptionSolitaire is a game played on a chessboard 8x8. The rows and columns of the chessboard are numbered from 1 to 8, from the top to the bottom and from left to right respectively.
There are four identical pieces on the board. In one move it is allowed to:
> move a piece to an empty neighboring field (up, down, left or right),
> jump over one neighboring piece to an empty field (up, down, left or right).
![](http://acm.hdu.edu.cn/data/images/1401-1.gif)
There are 4 moves allowed for each piece in the configuration shown above. As an example let's consider a piece placed in the row 4, column 4. It can be moved one row up, two rows down, one column left or two columns right.
Write a program that:
> reads two chessboard configurations from the standard input,
> verifies whether the second one is reachable from the first one in at most 8 moves,
> writes the result to the standard output.
Input
Each of two input lines contains 8 integers a1, a2, ..., a8 separated by single spaces and describes one configuration of pieces on the chessboard. Integers a2j-1 and a2j (1 <= j <= 4) describe the position of one piece - the row number and the column number
respectively. Process to the end of file.
Output
The output should contain one word for each test case - YES if a configuration described in the second input line is reachable from the configuration described in the first input line in at most 8 moves, or one word NO otherwise.
Sample Input
4 4 4 5 5 4 6 5
2 4 3 3 3 6 4 6
Sample Output
YES
解题思路:简单的bfs,难点在于状态判断,这里使用了八维数组,刚好不会超空间。即把4个棋子的坐标作为状态,在这之前要先对棋子排序,因为1 1 2 2 3 3 4 4和4 4 3 3 2 2 1 1 其实是一样的状态。之后就是简单的bfs了。另外这题可以用双向bfs,即两边同时bfs,如果在4步内,状态能达到一模一样,那证明可以在8步内达到,这样可以大大优化时间。这里用的是单向bfs,直接搜到8步。
#include <iostream> #include <stdio.h> #include <stdlib.h> #include <vector> #include <map> #include <string.h> #include <algorithm> #include <queue> using namespace std; bool vis[8][8][8][8][8][8][8][8]; int dx[4]={-1,1,0,0}; int dy[4]={0,0,-1,1}; struct point{ int x[4],y[4]; int t; point(int a1=0,int a2=0,int a3=0,int a4=0,int a5=0,int a6=0,int a7=0,int a8=0,int a=0){ x[0]=a1; y[0]=a2; x[1]=a3; y[1]=a4; x[2]=a5; y[2]=a6; x[3]=a7; y[3]=a8; t=a; adjust(); } void adjust(){ for(int i=0;i<4;i++) for(int j=i+1;j<4;j++){ if(x[i]>x[j]) { swap(x[i],x[j]); swap(y[i],y[j]); } else{ if(x[i]==x[j]){ if(y[i]>y[j]){ swap(x[i],x[j]); swap(y[i],y[j]); } } } } } }; point endp; point start; //判断两个点是否相等 bool same(point a,point b){ a.adjust(); b.adjust(); for(int i=0;i<4;i++){ if(a.x[i]!=b.x[i]) return false; if(a.y[i]!=b.y[i]) return false; } return true; } //判断是否要走两步,即该格子有没有棋子 bool have(int x,int y,point a){ for(int i=0;i<4;i++) if(a.x[i]==x&&a.y[i]==y) return true; return false; } bool bfs(){ queue<point> que; que.push(start); vis[start.x[0]-1][start.y[0]-1][start.x[1]-1][start.y[1]-1][start.x[2]-1][start.y[2]-1][start.x[3]-1][start.y[3]-1]=1; while(!que.empty()){ point tp=que.front(); que.pop(); if(tp.t>8) return false; if(same(tp,endp)) return true; int x,y; //4个棋子,4个方向 for(int i=0;i<4;i++){ for(int j=0;j<4;j++){ x=tp.x[i]+dx[j]; y=tp.y[i]+dy[j]; if(x==0||y==0||x==9||y==9) continue; if(have(x,y,tp)){ if(j==0) x--; if(j==1) x++; if(j==2) y--; if(j==3) y++; if(x==0||y==0||x==9||y==9) continue; if(!have(x,y,tp)){ if(i==0){ point temp=point(x,y,tp.x[1],tp.y[1],tp.x[2],tp.y[2],tp.x[3],tp.y[3],tp.t+1); if(vis[temp.x[0]-1][temp.y[0]-1][temp.x[1]-1][temp.y[1]-1][temp.x[2]-1][temp.y[2]-1][temp.x[3]-1][temp.y[3]-1]==0){ vis[temp.x[0]-1][temp.y[0]-1][temp.x[1]-1][temp.y[1]-1][temp.x[2]-1][temp.y[2]-1][temp.x[3]-1][temp.y[3]-1]=1; que.push(temp); } } if(i==1){ point temp=point(tp.x[0],tp.y[0],x,y,tp.x[2],tp.y[2],tp.x[3],tp.y[3],tp.t+1); if(vis[temp.x[0]-1][temp.y[0]-1][temp.x[1]-1][temp.y[1]-1][temp.x[2]-1][temp.y[2]-1][temp.x[3]-1][temp.y[3]-1]==0){ vis[temp.x[0]-1][temp.y[0]-1][temp.x[1]-1][temp.y[1]-1][temp.x[2]-1][temp.y[2]-1][temp.x[3]-1][temp.y[3]-1]=1; que.push(temp); } } if(i==2){ point temp=point(tp.x[0],tp.y[0],tp.x[1],tp.y[1],x,y,tp.x[3],tp.y[3],tp.t+1); if(vis[temp.x[0]-1][temp.y[0]-1][temp.x[1]-1][temp.y[1]-1][temp.x[2]-1][temp.y[2]-1][temp.x[3]-1][temp.y[3]-1]==0){ vis[temp.x[0]-1][temp.y[0]-1][temp.x[1]-1][temp.y[1]-1][temp.x[2]-1][temp.y[2]-1][temp.x[3]-1][temp.y[3]-1]=1; que.push(temp); } } if(i==3){ point temp=point(tp.x[0],tp.y[0],tp.x[1],tp.y[1],tp.x[2],tp.y[2],x,y,tp.t+1); if(vis[temp.x[0]-1][temp.y[0]-1][temp.x[1]-1][temp.y[1]-1][temp.x[2]-1][temp.y[2]-1][temp.x[3]-1][temp.y[3]-1]==0){ vis[temp.x[0]-1][temp.y[0]-1][temp.x[1]-1][temp.y[1]-1][temp.x[2]-1][temp.y[2]-1][temp.x[3]-1][temp.y[3]-1]=1; que.push(temp); } } } } else{ if(i==0){ point temp=point(x,y,tp.x[1],tp.y[1],tp.x[2],tp.y[2],tp.x[3],tp.y[3],tp.t+1); if(vis[temp.x[0]-1][temp.y[0]-1][temp.x[1]-1][temp.y[1]-1][temp.x[2]-1][temp.y[2]-1][temp.x[3]-1][temp.y[3]-1]==0){ vis[temp.x[0]-1][temp.y[0]-1][temp.x[1]-1][temp.y[1]-1][temp.x[2]-1][temp.y[2]-1][temp.x[3]-1][temp.y[3]-1]=1; que.push(temp); } } if(i==1){ point temp=point(tp.x[0],tp.y[0],x,y,tp.x[2],tp.y[2],tp.x[3],tp.y[3],tp.t+1); if(vis[temp.x[0]-1][temp.y[0]-1][temp.x[1]-1][temp.y[1]-1][temp.x[2]-1][temp.y[2]-1][temp.x[3]-1][temp.y[3]-1]==0){ vis[temp.x[0]-1][temp.y[0]-1][temp.x[1]-1][temp.y[1]-1][temp.x[2]-1][temp.y[2]-1][temp.x[3]-1][temp.y[3]-1]=1; que.push(temp); } } if(i==2){ point temp=point(tp.x[0],tp.y[0],tp.x[1],tp.y[1],x,y,tp.x[3],tp.y[3],tp.t+1); if(vis[temp.x[0]-1][temp.y[0]-1][temp.x[1]-1][temp.y[1]-1][temp.x[2]-1][temp.y[2]-1][temp.x[3]-1][temp.y[3]-1]==0){ vis[temp.x[0]-1][temp.y[0]-1][temp.x[1]-1][temp.y[1]-1][temp.x[2]-1][temp.y[2]-1][temp.x[3]-1][temp.y[3]-1]=1; que.push(temp); } } if(i==3){ point temp=point(tp.x[0],tp.y[0],tp.x[1],tp.y[1],tp.x[2],tp.y[2],x,y,tp.t+1); if(vis[temp.x[0]-1][temp.y[0]-1][temp.x[1]-1][temp.y[1]-1][temp.x[2]-1][temp.y[2]-1][temp.x[3]-1][temp.y[3]-1]==0){ vis[temp.x[0]-1][temp.y[0]-1][temp.x[1]-1][temp.y[1]-1][temp.x[2]-1][temp.y[2]-1][temp.x[3]-1][temp.y[3]-1]=1; que.push(temp); } } } } } } return false; } int main() { int a1=0, a2=0, a3=0, a4=0, a5=0, a6=0, a7=0, a8=0; while(cin>>a1>>a2>>a3>>a4>>a5>>a6>>a7>>a8){ start=point(a1,a2,a3,a4,a5,a6,a7,a8,0); cin>>a1>>a2>>a3>>a4>>a5>>a6>>a7>>a8; endp=point(a1,a2,a3,a4,a5,a6,a7,a8,0); memset(vis,0,sizeof(vis)); if(bfs()){ cout<<"YES"<<endl; } else cout<<"NO"<<endl; } return 0; }
相关文章推荐
- hdu 1401 Solitaire (双向广搜)
- HDU 1401 Solitaire (双向广搜)
- HDU 1401 Solitaire(双向广度优先搜索)
- HDU 1401 Solitaire 双向BFS
- hdu 1401 Solitaire 双向bfs
- HDU 1401 Solitaire
- poj 1198 hdu 1401 搜索+剪枝 Solitaire
- HDU 1401 Solitaire (双向搜索)
- hdu 1401 Solitaire(双向bfs)
- HDU 1401 Solitaire [双向BFS]
- HDU 1401 Solitaire
- HDU 1401 Solitaire 双向BFS
- hdu 1401 Solitaire(bfs)
- HDU 1401 Solitaire(双向搜索)
- hdu 1401/poj 1198 Solitaire(BFS,剪枝)
- hdu 1401 Solitaire(双向宽搜)
- HDU 1401 Solitaire(棋盘状态BFS)
- HDU 1401 Solitaire(双向BFS)
- HDU-1401 Solitaire 搜索
- hdu 1401 Solitaire 双向广度搜索