HDU1401 Solitaire 双向搜索
2012-01-05 14:51
239 查看
/* 很显然的BFS,没有悬念,只是实现起来有点麻烦 写完才发现,本题中,起点和终点都很明确,可以用双搜 不过我的单搜也没有超时 */ #include <iostream> #include <algorithm> #include <map> #include <queue> using namespace std; //状态 struct node { char ch[4];//用char类型是为了省空间 int ceil; }; //判断两个状态是否为同一状态 int equal(const node& a,const node& b) { int i = 0, j = 0, ans = 0; while(i < 4&&j<4) { if(a.ch[i] == b.ch[j]) { ans++; i++; j++; } else if(a.ch[i] < b.ch[j]) i++; else if(a.ch[i] > b.ch[j]) j++; } return ans; } queue<node> Q; map<int, int> M;//避免状态重复 bool m[9][9]; int main() { int a1[8], a2[8], i, j, id; node start, end, p, q; bool flag; while(cin>>a1[0]) { flag = 0;id = 0; //输入目标状态 for(i = 1; i < 8; i++) cin>>a1[i]; //输入初始状态 for(i = 0; i < 8; i++) cin>>a2[i]; //记录初始状态,每个char存储两位数,分别是横坐标与纵坐标 for(i = 0; i < 4; i++) { start.ch[i] = (a2[2*i])*10+a2[2*i+1]; id = id * 100 + start.ch[i]; } //将四个点按顺序存储,有利于后续操作 sort(start.ch, start.ch+4); start.ceil = 0; //同样方法处理目标状态 for(i = 0; i < 4; i++) end.ch[i] = (a1[2*i])*10+a1[2*i+1]; sort(end.ch, end.ch+4); //典型的BFS while(!Q.empty())Q.pop(); M.clear(); M[id] = 1; Q.push(start); while(!Q.empty()) { p = Q.front(); Q.pop(); if(p.ceil > 8)break; int ans = equal(p, end); if(ans == 4) { flag = 1; break; } //优化:如果还能走2步,却有3个棋子没有在目标位置上,肯定不能成功 if(ans < p.ceil - 4) continue; memset(m, 0, sizeof(m)); //析出状态对应的坐标 for(i = 0; i < 4; i++) { int temp = (int)p.ch[i]; m[temp/10][temp%10] = 1; } //下一步 for(i = 0; i < 4; i++) { int temp = (int)p.ch[i]; int x = temp/10, y = temp%10; //上 q = p;q.ceil++; if(x > 1) { //下一步是空的,就走下一步 if(m[x-1][y] == 0) { q.ch[i] = (x-1)*10+y; sort(q.ch, q.ch+4); id = 0; for(j = 0; j < 4; j++) id = id * 100 + q.ch[j]; if(M[id] == 0) { Q.push(q); M[id] = 1; } } //下一步是棋子,下下步是空的,就跳一步 else { if(x > 2 && m[x-2][y] == 0) { q.ch[i] = (x-2)*10+y; sort(q.ch, q.ch+4); id = 0; for(j = 0; j < 4; j++) id = id * 100 + q.ch[j]; if(M[id] == 0) { Q.push(q); M[id] = 1; } } } } //下 q = p;q.ceil++; if(x < 8) { if(m[x+1][y] == 0) { q.ch[i] = (x+1)*10+y; sort(q.ch, q.ch+4); id = 0; for(j = 0; j < 4; j++) id = id * 100 + q.ch[j]; if(M[id] == 0) { Q.push(q); M[id] = 1; } } else { if(x < 7 && m[x+2][y] == 0) { q.ch[i] = (x+2)*10+y; sort(q.ch, q.ch+4); id = 0; for(j = 0; j < 4; j++) id = id * 100 + q.ch[j]; if(M[id] == 0) { Q.push(q); M[id] = 1; } } } } //左 q = p;q.ceil++; if(y > 1) { if(m[x][y-1] == 0) { q.ch[i] = x*10+y-1; sort(q.ch, q.ch+4); id = 0; for(j = 0; j < 4; j++) id = id * 100 + q.ch[j]; if(M[id] == 0) { Q.push(q); M[id] = 1; } } else { if(y > 2 && m[x][y-2] == 0) { q.ch[i] = x*10+y-2; sort(q.ch, q.ch+4); id = 0; for(j = 0; j < 4; j++) id = id * 100 + q.ch[j]; if(M[id] == 0) { Q.push(q); M[id] = 1; } } } } //右 q = p;q.ceil++; if(y < 8) { if(m[x][y+1] == 0) { q.ch[i] = x*10+y+1; sort(q.ch, q.ch+4); id = 0; for(j = 0; j < 4; j++) id = id * 100 + q.ch[j]; if(M[id] == 0) { Q.push(q); M[id] = 1; } } else { if(y < 7 && m[x][y+2] == 0) { q.ch[i] = x*10+y+2; sort(q.ch, q.ch+4); id = 0; for(j = 0; j < 4; j++) id = id * 100 + q.ch[j]; if(M[id] == 0) { Q.push(q); M[id] = 1; } } } } } } if(flag)cout<<"YES"<<endl; else cout<<"NO"<<endl; } return 0; }
相关文章推荐
- Hdu1401-Solitaire(双向bfs)
- hdu 1401 Solitaire 双向广度搜索
- HDU 1401 Solitaire(双向搜索)
- hdu1401 Solitaire ----双向BFS
- HDU 1401 Solitaire (双向搜索)
- hdu1401 Solitaire (双向bfs)
- hdu 1401 Solitaire(双向bfs)
- POJ 1915 Knight Moves 双向搜索
- CodeForces-920E Connected Components? 广度搜索 双向链表 判断联通 大量重复节点的删除
- uva208 -Firetruck (双向搜索进行剪枝)
- 双向BFS搜索和A*算法
- poj 1198 hdu 1401 搜索+剪枝 Solitaire
- 【TOJ 3403】Treasure Division 【双向搜索】
- codeforces 888E Maximum Subsequence (折半枚举 双向搜索)
- HDU 1401 Solitaire 双向BFS
- 双向搜索法 ------推箱子算法简要分析
- POJ 2785 4 Values whose Sum is 0(双向搜索+二分)
- 搜索二叉树转化为双向链表
- hdu 1401 Solitaire 双向bfs
- uva 1601 poj 3523 Morning after holloween 万圣节后的早晨 (经典搜索,双向bfs+预处理优化+状态压缩位运算)