Aizu 0121 Seven Puzzle(变进制数的完美hash)
2015-10-18 15:38
393 查看
一遍预处理跑完所有情况,O(1)回答就好。状态记录我用的康拓和逆康拓。
#include<bits/stdc++.h> using namespace std; int d[40320]; int fac[8]; int u[8]; int cantor() { int re = 0; for(int i = 0; i < 8; i++){ int inv = 0; for(int j = i; ++j < 8; ){ if(u[i]>u[j]) inv++; } re += fac[7-i]*inv; } return re; } void invCantor(int x) { bool vis[8] = {}; for(int i = 0; i < 8; i++){ int w = x/fac[7-i]; x %= fac[7-i]; int j = 0; for( ; j < 8; j++){ if(!vis[j]){ if(!w) break; w--; } } u[i] = j; vis[j] = true; } } int cur; queue<int> q; inline void updata(int p0,int p1) { swap(u[p0],u[p1]); int s = cantor(); if(!d[s]){ d[s] = d[cur]+1; q.push(s); } swap(u[p0],u[p1]); } void bfs() { d[0] = 1; q.push(0); while(q.size()){ invCantor(cur = q.front()); q.pop(); int p; for(int i = 0; i < 8; i++) if(!u[i]){ p = i; break; } int r = p%4; if(r) { updata(p-1,p); } if(r<3){ updata(p+1,p); } updata(p,p+(p>3?-4:4)); } } void preDeal() { fac[0] = 1; for(int i = 1; i < 8; i++){ fac[i] = fac[i-1]*i; } bfs(); } int read() { if(scanf("%d",u)<0) return -1; for(int i = 1; i < 8; i++) scanf("%d",u+i); return cantor(); } //#define LOCAL int main() { #ifdef LOCAL freopen("in.txt","r",stdin); #endif preDeal(); int s; while( ~(s = read()) ){ printf("%d\n",d[s]-1); } return 0; }
相关文章推荐
- Adb failed to restart 的解决办法
- MFC中的Invalidate、OnDraw、OnPaint函数的作用、区别和联系
- Aizu 0033 Ball(dfs,贪心)
- Aizu 2170 Marked Ancestor(并查集变形)
- POJ 2010 Moo University - Financial Aid(堆维护滑窗kth,二分)
- 正确理解wait()和notify()方法
- NDK链接main(可执行)链接so
- phalapi-进阶篇1(Api,Domain,和Model)
- grails邮件服务
- 20.Climbing Stairs
- HDU 4770 Lights Against Dudely(二进制枚举子集)
- Error:Execution failed for task ':asynctask:packageDebug'
- UVa1326--Jurassic Remains(折半搜索)
- RAID基础知识总结
- iframe与主框架跨域相互访问方法
- Outlook 2013 重新联姻Hotmail ,Exchange ActiveSync牵线搭桥
- Django使用email进行身份验证
- Brain的同步规则
- 解决:打开OleView报错 dllregisterserver in iviewers failed
- C++中智能指针的设计和使用 http://blog.csdn.net/hackbuteer1/article/details/7561235