1. 程式人生 > >Vijos CoVH之再破難關(搜索+hash)

Vijos CoVH之再破難關(搜索+hash)

ash pen inline src sed blog node 輸出 data

背景

在瞬間之下,明白所有真相
只要開始,就不會停止...

揭開唯一事實,外表是小孩,頭腦卻是大人
他的名字就叫...名偵探柯南!

描述

[CoVH07]
OIBH組織派出的黃金十二人+青銅五小強還沒有到, 他們只能指望原先的機關能夠阻攔住柯南的腳步.

柯南打開大門之後發現裏面還有一個門, 門上還有一個神奇的鎖(-,-)

這是一個4*4的鎖, 上面有8個凸起的格子和8個被按下的格子
當且僅當兩個格子有公共邊時, 則稱這兩個格子是相鄰的。

技術分享
每次操作只能夠交換相鄰的兩個格子

柯南看到了初始鎖的狀態 和目標鎖的狀態
同樣組織只允許他用最少步數打開鎖

格式

輸入格式

第1到4行每行四個數字(1或者0),描述了初始鎖狀態

接著是一個空行

第6到9行每行四個數字,描述了最終鎖狀態

輸出格式

輸出文件只有一行,是一個整數n,表示最少的操作次數。

樣例1

樣例輸入1

1111
0000
1110
0010

1010
0101
1010
0101
Copy

樣例輸出1

4
Copy

限制

全部1秒

提示

柯南成功突破了又一道門
他將繼續向前進
而黃金十二人+青銅五小強又在哪裏.......

來源

提供:*******@***牛
對他的無私貢獻表示崇拜和感謝!@_@

成功拉低了1%的AC率

技術分享
 1 /*
 2     bfs+數組判重
 3     狀態很少 只有2^16
4 直接用數組就好了 5 */ 6 #include<map> 7 #include<cstdio> 8 #include<iostream> 9 #define MAXN 400010 10 11 using namespace std; 12 13 struct node { 14 int a[4][4]; 15 }; 16 node e[MAXN]; 17 18 int mp[4][4]; 19 20 int step[MAXN],head,tail; 21 22 int x[4]= {0,1
,0,-1}; 23 int y[4]= {1,0,-1,0}; 24 25 char s[10]; 26 27 bool flag,_HASH[1300000]; 28 29 map<node,int> m; 30 31 inline bool pd(int xx,int yy) { 32 if(xx<0||yy<0) return false; 33 if(xx>=4||yy>=4) return false;// 啊啊mdzz 這裏忘了‘=’ 害我錯了18次 34 else return true; 35 } 36 37 inline bool check() { 38 for(int i=0; i<4; i++) 39 for(int j=0; j<4; j++) 40 if(mp[i][j]!=e[tail].a[i][j]) return false; 41 return true; 42 } 43 44 inline bool _hash() { 45 int now=0; 46 for(int i=0;i<4;i++) 47 for(int j=0;j<4;j++) { 48 now<<=1; 49 now+=e[tail].a[i][j]; 50 } 51 if(_HASH[now]) return false; 52 _HASH[now]=true; 53 return true; 54 } 55 56 inline void search() { 57 while(head<tail) { 58 for(int xx=0; xx<4; xx++) 59 for(int yy=0; yy<4; yy++) 60 for(int i=0; i<4; i++) { 61 int _x=xx+x[i]; 62 int _y=yy+y[i]; 63 if(pd(_x,_y)) { 64 for(int i=0; i<4; i++) 65 for(int j=0; j<4; j++) 66 e[tail].a[i][j]=e[head].a[i][j]; 67 step[tail]=step[head]+1; 68 swap(e[tail].a[_x][_y],e[tail].a[xx][yy]); 69 if(check()) { 70 printf("%d\n",step[tail]); 71 return; 72 } 73 if(_hash()) tail++; 74 } 75 } 76 head++; 77 } 78 } 79 80 int main() { 81 for(int i=0; i<4; i++) { 82 scanf("%s",s); 83 for(int j=0; j<4; j++) 84 mp[i][j]=s[j]-48; 85 } 86 for(int i=0; i<4; i++) { 87 scanf("%s",s); 88 for(int j=0; j<4; j++) 89 e[0].a[i][j]=s[j]-48; 90 } 91 if(check()) { 92 printf("0\n"); 93 return 0; 94 } 95 tail=1; 96 search(); 97 return 0; 98 }
代碼

Vijos CoVH之再破難關(搜索+hash)