HDU 1401 Solitaire
来源:互联网 发布:玻璃优化排版软件 编辑:程序博客网 时间:2024/05/17 15:20
Solitaire
Time Limit : 2000/1000ms (Java/Other) Memory Limit : 65536/32768K (Java/Other)
Total Submission(s) : 12 Accepted Submission(s) : 1
Problem Description
Solitaire 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).
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.
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).
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 52 4 3 3 3 6 4 6
Sample Output
YES
Source
Southwestern Europe 2002
双向广搜。 每组棋子的坐标为1~8 共有四个坐标 8个数都可以用三个二进制数保存 所以可以将状态转换为相应的十进制数进行状态压缩
只能走八步,每步有十六中变化 所以双向广搜可以解决
#include<iostream>#include<cstdio>#include<cstring>#include<queue>#include<map>#include<algorithm>using namespace std;struct Point{ int x,y; bool cheak() { if(x>=0&&x<8&&y>=0&&y<8) return true ; else return false ; }};struct node{ Point a[5]; int t;} st,ed,e;int dir[4][2]= {0,1,0,-1,1,0,-1,0};bool vis[16777216+1]; //标记 状态压缩int us[65536+10]; //记录出现过的状态int len;bool cmp(Point n1,Point n2){ return n1.x!=n2.x?n1.x<n2.x:n1.y<n2.y;}int get_hash(Point *tmp) //状态压缩{ int res=0; sort(tmp,tmp+4,cmp); for(int i=0; i<4; i++) { res|=(tmp[i].x<<(6*i)); res|=(tmp[i].y<<(6*i+3)); } return res;}bool fine(int num) //二分查找{ int l=0,r=len-1; while(l<=r) { int mid=(l+r)/2; if(num==us[mid]) return true ; if(num>us[mid]) l=mid+1; else r=mid-1; } return false ;}void dfs(){ queue<node>q; memset(vis,false ,sizeof(vis)); len=0; int Hash; Hash=get_hash(st.a); vis[Hash]=true ; us[len++]=Hash; st.t=0; q.push(st); int k; //起点开始广搜可以出现的状态 while(q.size()) { st=q.front(); q.pop(); if(st.t>=4) continue ; for(int j=0; j<4; j++) { for(int i=0; i<4; i++) { e=st; e.t++; e.a[i].x+=dir[j][0]; e.a[i].y+=dir[j][1]; if(!e.a[i].cheak()) continue ; for(k=0; k<4; k++) { if(k!=i&&e.a[k].x==e.a[i].x&&e.a[k].y==e.a[i].y) break; } if(k==4) { Hash=get_hash(e.a); if(!vis[Hash]) { vis[Hash]=true ; us[len++]=Hash; q.push(e); } } else { e.a[i].x+=dir[j][0]; e.a[i].y+=dir[j][1]; if(!e.a[i].cheak()) continue ; for(k=0; k<4; k++) { if(k!=i&&e.a[k].x==e.a[i].x&&e.a[k].y==e.a[i].y) break; } if(k==4) { Hash=get_hash(e.a); if(!vis[Hash]) { vis[Hash]=true ; us[len++]=Hash; q.push(e); } } } } } } sort(us,us+len); memset(vis,false ,sizeof(vis)); Hash=get_hash(ed.a); if(fine(Hash)) //从起点走出现过这种状态 { printf("YES\n"); return ; } vis[Hash]=true ; q.push(ed); while(q.size()) { st=q.front(); q.pop(); if(st.t>=4) continue ; for(int j=0; j<4; j++) { for(int i=0; i<4; i++) { e=st; e.t++; e.a[i].x+=dir[j][0]; e.a[i].y+=dir[j][1]; if(!e.a[i].cheak()) continue ; for(k=0; k<4; k++) { if(k!=i&&e.a[k].x==e.a[i].x&&e.a[k].y==e.a[i].y) break; } if(k==4) { Hash=get_hash(e.a); if(fine(Hash)) { printf("YES\n"); return ; } if(!vis[Hash]) { vis[Hash]=true ; q.push(e); } } else { e.a[i].x+=dir[j][0]; e.a[i].y+=dir[j][1]; if(!e.a[i].cheak()) continue ; for(k=0; k<4; k++) { if(k!=i&&e.a[k].x==e.a[i].x&&e.a[k].y==e.a[i].y) break; } if(k!=4) continue ; Hash=get_hash(e.a); if(fine(Hash)) { printf("YES\n"); return ; } if(!vis[Hash]) { vis[Hash]=true ; q.push(e); } } } } } printf("NO\n"); return ;}int main(){ while(~scanf("%d%d",&st.a[0].x,&st.a[0].y)) { for(int i=1; i<4; i++) scanf("%d%d",&st.a[i].x,&st.a[i].y); st.t=0; for(int i=0; i<4; i++) scanf("%d%d",&ed.a[i].x,&ed.a[i].y); ed.t=0; //将坐标转为0~7对应2^3-1的数 状态压缩 for(int i=0; i<4; i++) { st.a[i].x--; st.a[i].y--; ed.a[i].x--; ed.a[i].y--; } dfs(); } return 0;}
0 0
- HDU-1401 Solitaire 搜索
- hdu 1401 Solitaire(bfs)
- 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 [双向BFS]
- HDU 1401 Solitaire(双向BFS)
- hdu 1401 Solitaire(双向bfs)
- HDU 1401 Solitaire(棋盘状态BFS)
- HDU 1401 Solitaire (双向广搜)
- poj 1198 hdu 1401 搜索+剪枝 Solitaire
- HDU 1401 Solitaire (双向搜索)
- HDU 1401 Solitaire(双向广度优先搜索)
- hdu 1401/poj 1198 Solitaire(BFS,剪枝)
- hdu 1401 Solitaire(双向宽搜)
- 归档
- poj 1631 Bridging signals dp LIS
- Light OJ 1354 - IP Checking 【二进制转化】
- 数据结构基础5.3:平衡二叉树(AVL树)的调整
- ApplicationOnline_Tips&Review
- HDU 1401 Solitaire
- Physics.IgnoreLayerCollision没有效果
- 有序数组的查询
- Java第一次写的流布局图形界面,留个纪念
- zufe oj Problem H: 简单数学题 java
- Git基础操作<二>
- JS-语句
- C++智能指针
- iOS中的GCD(2)---获取队列方法