zoj 3814 Sawtooth Puzzle(隐式图搜索)
来源:互联网 发布:mac wifi共享软件 编辑:程序博客网 时间:2024/05/20 04:14
题目链接:zoj 3814 Sawtooth Puzzle
题目大意:给定一个9宫拼图,每次可以挑选一个位置顺时针旋转,和普通拼图不一样的是每块拼图周围可能有齿转动一个可能导致全部拼图转变。
解题思路:隐式图搜索,9块拼图最多49个状态,对于每个状态枚举转动的位置,考虑转动的状态。一开始转移是用bfs写的,但是由于频繁申请队列,然后时间爆了
#include <cstdio>#include <cstring>#include <queue>#include <set>#include <algorithm>using namespace std;typedef long long ll;typedef char Mat[10][10];const int maxn = 9;const int maxm = 4;const int maxs = 1<<18;const int dir[4][2] = { {0, -1}, {-1, 0}, {0, 1}, {1, 0} };Mat sb[maxn], se[maxn];int mesh[maxn][maxm];inline int hash_state(int* c) { int ret = 0; for (int i = 0; i < maxn; i++) ret = ret * maxm + c[i]; return ret;}inline void reback(int p, int* c) { for (int i = maxn-1; i >= 0; i--) { c[i] = p % maxm; p /= maxm; }}void rotate (Mat u);int vis[maxs+5], c[maxn+5];set<int> stop;void dfs (int d, int s) { if (d >= maxn) { stop.insert(s); return; } for (int i = 0; i < 4; i++) { if (memcmp(sb[d], se[d], sizeof(se[d])) == 0) dfs(d+1, s * maxm + i); rotate(sb[d]); }}void init () { stop.clear(); for (int i = 0; i < 3; i++) { for (int k = 0; k < 8; k++) { for (int j = 0; j < 3; j++) scanf("%s", sb[i*3+j][k]); } } for (int i = 0; i < 3; i++) { for (int k = 0; k < 8; k++) { for (int j = 0; j < 3; j++) scanf("%s", se[i*3+j][k]); } } dfs(0, 0); for (int i = 0; i < maxn; i++) { for (int j = 0; j < maxm; j++) scanf("%d", &mesh[i][j]); }}void get(int u, int* t) { for (int i = 0; i < 4; i++) { int p = u / 3 + dir[i][0]; int q = u % 3 + dir[i][1]; int v = p * 3 + q; if (p < 0 || p >= 3 || q < 0 || q >= 3 || c[v]) continue; if (mesh[u][(t[u] + i) % maxm] && mesh[v][(t[v] + i + 2) % maxm]) { c[v] = -c[u]; get(v, t); } }}int solve (int* t, int x) { memset(c, 0, sizeof(c)); c[x] = -1; get(x, t); int ret = 0; for (int i = 0; i < maxn; i++) ret = ret * 4 + (t[i] + c[i] + maxm) % maxm; return ret;}int bfs() { if (stop.size() == 0) return -1; queue<int> que; memset(vis, -1, sizeof(vis)); que.push(0); vis[0] = 0; if (stop.find(0) != stop.end()) return 0; int t[maxn+5]; while (!que.empty()) { int u = que.front(); que.pop(); reback(u, t); for (int i = 0; i < maxn; i++) { int v = solve(t, i); if (vis[v] >= 0) continue; vis[v] = vis[u] + 1; que.push(v); if (stop.find(v) != stop.end()) return vis[v]; } } return -1;}int main () { int cas; scanf("%d", &cas); while (cas--) { init(); printf("%d\n", bfs()); } return 0;}void rotate (Mat u) { Mat v; memset(v, 0, sizeof(v)); for (int i = 0; i < 8; i++) { for (int j = 0; j < 8; j++) v[7-j][i] = u[i][j]; } memcpy(u, v, sizeof(v));}
0 0
- zoj 3814 Sawtooth Puzzle(隐式图搜索)
- ZOJ 3814 Sawtooth Puzzle 状态压缩搜索
- zoj 3814 Sawtooth Puzzle(搜索-bfs)
- zoj 3814 Sawtooth Puzzle
- BFS ZOJ 3814 Sawtooth Puzzle
- [ZOJ 3814 Sawtooth Puzzle] bfs+状态压缩
- ZOJ 3814 / 2014 牡丹江赛区网络赛 F. Sawtooth Puzzle
- ZOJ 3814 Sawtooth Puzzle(牡丹江网络赛F题)
- ZOJ 3814 Sawtooth Puzzle (2014年牡丹江赛区网络赛F题)
- zoj 3019 Puzzle
- ZOJ 3019 Puzzle【水】
- zoj 3091 Puzzle
- zoj 3019 Puzzle
- zoj 1602 Multiplication Puzzle
- ZOJ 1602 Multiplication Puzzle
- ZOJ 3019 Puzzle
- zoj 3019 Puzzle
- ZOJ 2610 Puzzle 模拟
- Ubuntu上安装部署redis
- 实战Memcached缓存系统(4)Memcached的CAS协议
- iOS开发13:UITableView与UITableViewCell
- Ubuntu 12.04搭建MTK 6577 安卓开发环境
- table control 双击事件
- zoj 3814 Sawtooth Puzzle(隐式图搜索)
- rbm C++代码理解
- Webkit学习 ----网页资源的构建加载流程
- Socket网络编程--epoll小结
- iOS 打开本地沙盒文件
- Java序列化的作用解析
- HTML块状元素、内联元素
- 数据结构复习总结
- js获取、控制 回车事件。