【[HAOI2008]移動玩具】
阿新 • • 發佈:2019-02-11
-o pan map 狀態 print scan etc push 行操作
並不知道省選考這種爆搜題有什麽意義。。
正文部分:
觀察題目中只有12個數,每個數只有0和1,明顯所以狀態的數量為\(2^{12}=4096\),那豈不是爆搜隨便做?
對於1個狀態hash:
我們將現在這12位數打包成一個字符串,用\(map\)記錄一下這個字符串是否出現過。
對於1個狀態的unhash,我們將這個字符串轉到1個矩陣裏,就是當前的狀態。
於是我們就可以輕松的得到每種情況的狀態。
對於Bfs過程,我們對unhash完的矩陣進行操作,每次選取其中為1的點,分4個方向向外擴散,然後壓成1個新的狀態,如此繼續。
My Code:
// luogu-judger-enable-o2 #include <bits/stdc++.h> #define il inline #define gc getchar using namespace std; string S,T; char x; map<string,bool> vis; int n,m,i,j,k; int dir[4][2] = {{0,-1},{0,1},{-1,0},{1,0}}; int tmp[5][5]; struct Bfs { string zt;int step; }; il int read() { int res = 0;char c;bool sign = 0; for(c = gc();!isdigit(c);c = gc()) sign |= c == ‘-‘; for(;isdigit(c);c = gc()) res = (res << 1) + (res << 3) + (c ^ 48); return sign ? -res : res; } il void unhash(string s,int a[5][5]) { int i,j,id = 0; for(i = 1;i <= 4;i++) { for(j = 1;j <= 4;j++) { a[i][j] = s[id];id++; } } return; } il string hash(int a[5][5]) { int i,j;string res = ""; for(i = 1;i <= 4;i++) { for(j = 1;j <= 4;j++) { res += a[i][j]; } }return res; } il void print(int a[5][5]) { int i,j; for(i = 1;i <= 4;i++) { for(j = 1;j <= 4;j++) { printf("%d%c",a[i][j],j == n ? ‘\n‘ : ‘ ‘); } } } il void bfs(string s,string t) { queue<Bfs> Q;while(!Q.empty()) Q.pop(); Q.push((Bfs){s,0});vis[s] = 1; while(!Q.empty()) { string zt = Q.front().zt;int step = Q.front().step; Q.pop(); if(zt == T) { printf("%d",step); exit(0); } unhash(zt,tmp);int i,j,k; // print(tmp); for(i = 1;i <= 4;i++) { for(j = 1;j <= 4;j++) { if(!tmp[i][j]) continue; for(k = 0;k < 4;k++) { int nx = i + dir[k][0]; int ny = j + dir[k][1]; if(nx < 1 || nx > 4 || ny < 1 || ny > 4) continue; if(tmp[nx][ny]) continue; tmp[nx][ny] = 1;tmp[i][j] = 0; string new_zt = hash(tmp); if(!vis[new_zt]) { vis[new_zt] = 1; Q.push((Bfs){new_zt,step + 1}); } tmp[nx][ny] = 0;tmp[i][j] = 1; } } } } } int main() { S = T = ""; for(i = 1;i <= 4;i++) { for(j = 1;j <= 4;j++) { scanf("%c",&x); while(!isdigit(x)) scanf("%c",&x); S += x - 48; } } for(i = 1;i <= 4;i++) { for(j = 1;j <= 4;j++) { scanf("%c",&x); while(!isdigit(x)) scanf("%c",&x); T += x - 48; } } bfs(S,T); return 0; }
【[HAOI2008]移動玩具】