[ZOJ 3814 Sawtooth Puzzle] bfs+状态压缩
来源:互联网 发布:行业评选网络投票 编辑:程序博客网 时间:2024/05/17 18:47
题目
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3814
分析
可以发现对于两个相邻的格子并且他们相邻的边都是有锯齿的,那么他们的旋转的。进一步可以得知他们的影响关系如果出现循环也不会有矛盾,因此可以简单模拟旋转过程。
易知每个格子最多有四种状态,我们可以用4^9来表示所有的状态,然后暴力搜索,模拟其中的旋转过程就可以了。
注意一个地方,就是目标状态的判断。因为不同状态表示的实际格子状态可能是相同的,对目标状态九个格子要分别判断哪些压缩后的状态是合法的,只要出现一种合法状态就找到了解。
代码
#include<cstring>#include<string>#include<cstdio>#include<cstdlib>#include<iostream>#include<vector>#include<algorithm>#include<cmath>#include<queue>using namespace std;#define ll long long#define pf printf#define sf scanf#define Fill(a,b) memset(a,b,sizeof(a))struct State{ int st[11]; State(){} State(int a1,int a2,int a3,int a4,int a5,int a6,int a7,int a8,int a9) { st[1] = a1; st[2] = a2; st[3] = a3; st[4] = a4; st[5] = a5; st[6] = a6; st[7] = a7; st[8] = a8; st[9] = a9; }};queue<State>q;string s[10][10],t[10][10],p[10];int st[11][11];int tp[5][5];bool sol[11];bool cor[11][11];int f[1 << 20];int ans;const int up[] = {0,0,0,0,1,2,3,4,5,6};const int down[] = {0,4,5,6,7,8,9,0,0,0};const int lef[] = {0,0,1,2,0,4,5,0,7,8};const int rig[] = {0,2,3,0,5,6,0,8,9,0};inline void Init_initial(){ for (int i = 1; i <= 8; i++) for (int j = 1; j <= 3; j++) cin>>s[j][i]; for (int i = 1; i <= 8; i++) for (int j = 4; j <= 6; j++) cin>>s[j][i]; for (int i = 1; i <= 8; i++) for (int j = 7; j <= 9; j++) cin>>s[j][i];}inline void Init_target(){ for (int i = 1; i <= 8; i++) for (int j = 1; j <= 3; j++) cin>>t[j][i]; for (int i = 1; i <= 8; i++) for (int j = 4; j <= 6; j++) cin>>t[j][i]; for (int i = 1; i <= 8; i++) for (int j = 7; j <= 9; j++) cin>>t[j][i];}inline int trans(State x){ int ans = 0; for (int i = 1; i <= 9; i++) ans = ans + (x.st[i] << (2 * (i - 1))); return ans;}inline bool meshed(State x,int a,int e1,int b,int e2){ int f1 = st[a][tp[x.st[a]][e1]],f2 = st[b][tp[x.st[b]][e2]]; return (f1 == 1 && f2 == 1);}inline State rotate(State x,int y,int flag){ sol[y] = 1; int l = lef[y],r = rig[y],u = up[y],d = down[y]; bool fl = 0,fu = 0,fd = 0,fr = 0; if (l != 0 && !sol[l] && meshed(x,l,3,y,1)) fl = 1; if (r != 0 && !sol[r] && meshed(x,r,1,y,3)) fr = 1; if (u != 0 && !sol[u] && meshed(x,u,4,y,2)) fu = 1; if (d != 0 && !sol[d] && meshed(x,d,2,y,4)) fd = 1; int z = x.st[y]; if (flag == 1) { z = z + 1; if (z == 4) z = 0; } else { z = z - 1; if (z == -1) z = 3; } x.st[y] = z; if (fl && !sol[l]) { sol[l] = 1; x = rotate(x,l,3 - flag); } if (fr && !sol[r]) { sol[r] = 1; x = rotate(x,r,3 - flag); } if (fu && !sol[u]) { sol[u] = 1; x = rotate(x,u,3 - flag); } if (fd && !sol[d]) { sol[d] = 1; x = rotate(x,d,3 - flag); } return x;}inline bool ok(State y){ for (int i = 1; i <= 9; i++) if (!cor[i][y.st[i]]) return 0; return 1;}inline void bfs(State x){ while (!q.empty()) q.pop(); q.push(x); while (!q.empty()) { x = q.front(); q.pop(); int sx = trans(x); for (int i = 1; i <= 9; i++) { Fill(sol,0); State y = rotate(x,i,1); int sy = trans(y); if (f[sy] > f[sx] + 1) { f[sy] = f[sx] + 1; if (ok(y)) { ans = f[sy]; return; } q.push(y); } } }}inline bool same(int x){ for (int i = 1; i <= 8; i++) for (int j = 0; j < 8; j++) if (s[x][i][j] != t[x][i][j]) return 0; return 1;}inline void change(int x){ for (int i = 1; i <= 8; i++) p[i] = ""; for (int i = 1; i <= 8; i++) for (int j = 8; j >= 1; j--) p[i] = p[i] + s[x][j][i - 1]; for (int i = 1; i <= 8; i++) s[x][i] = p[i];}int main(){ // freopen("in.txt","r",stdin); int T; sf("%d",&T); for (int TT = 1; TT <= T; TT++) { Init_initial(); Init_target(); for (int i = 1; i <= 9; i++) for (int j = 1; j <= 4; j++) sf("%d",&st[i][j]); Fill(f,63); tp[0][1] = 1; tp[0][2] = 2; tp[0][3] = 3; tp[0][4] = 4; tp[1][1] = 4; tp[1][2] = 1; tp[1][3] = 2; tp[1][4] = 3; tp[2][1] = 3; tp[2][2] = 4; tp[2][3] = 1; tp[2][4] = 2; tp[3][1] = 2; tp[3][2] = 3; tp[3][3] = 4; tp[3][4] = 1; f[0] = 0; ans = -1; Fill(cor,0); for (int i = 1; i <= 9; i++) for (int j = 0; j < 4; j++) { if (same(i)) cor[i][j] =1; change(i); } bfs(State(0,0,0,0,0,0,0,0,0)); pf("%d\n",ans); } return 0;}
0 0
- [ZOJ 3814 Sawtooth Puzzle] bfs+状态压缩
- ZOJ 3814 Sawtooth Puzzle 状态压缩搜索
- BFS ZOJ 3814 Sawtooth Puzzle
- zoj 3814 Sawtooth Puzzle(搜索-bfs)
- zoj 3814 Sawtooth Puzzle
- zoj 3814 Sawtooth Puzzle(隐式图搜索)
- ZOJ 3814 / 2014 牡丹江赛区网络赛 F. Sawtooth Puzzle
- ZOJ 3814 Sawtooth Puzzle(牡丹江网络赛F题)
- ZOJ 3814:模拟和状态压缩BFS
- ZOJ 3611 BFS+状态压缩
- ZOJ 3814 Sawtooth Puzzle (2014年牡丹江赛区网络赛F题)
- ZOJ-2050-Flip Game【状态压缩bfs】
- ZOJ 3596 Digit Number【状态压缩】【BFS】
- zoj 3652 ZOJ 3652 MAZE(BFS+状态压缩)
- zoj 2050 || poj 1753 Flip Game(状态压缩 简单BFS)
- zoj 1505 || poj 1198 Solitaire(状态压缩+双向BFS)
- ZOJ 3675 Trim the Nails (状态压缩+BFS)
- ZOJ 3596 Digit Number(状态压缩 + BFS)
- Android集成ZXing二维码扫描,附加竖屏并且不拉伸图片的demo
- NSDictionary类使用
- 【leetcode】链表常见题目总结
- word-wrap和word-break的区别
- android目前最快的模拟器(genymotion)的安装
- [ZOJ 3814 Sawtooth Puzzle] bfs+状态压缩
- float与double的范围和精度
- JavaWEb基础之实现验证码
- [Clojure] Data Collection and Data Analysis on the music of www.xiami.com - Part 2
- JSON解析步骤
- fork()创建子进程步骤、函数用法及常见考点(内附fork()过程图)
- 手机高阶技巧大全
- 手动配置Hibernate
- int ,long , long long,__int64类型的范围