2022.3.17
阿新 • • 發佈:2022-03-17
藍書
AcWing 185. 瑪雅游戲
思路:由於n<=5,可以暴力搜尋,但是要模擬很多過程非常麻煩,當三個或以上的相同顏色的塊連在一起的時候得把他們同時刪去。同時還得判斷是否能夠構成方案,如果最後有任意一個顏色的塊的數量為<=2說明肯定不能連成三個以上的了,這時就說明無解。首先讀入的時候將所有有顏色的塊的和以及它們分別和都求出來。在dfs的時候判斷當前是想左還是向右,然後進行交換。在更新狀態的時候需要吧懸空的塊都讓他落下來,並且還要檢視哪些塊是連在一起的然後將他們刪除,此時還需要更新總和和各自的和。記得還要備份和還原現場。
寫了一上午還是沒有寫出來,最後看了題解。
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> using namespace std; typedef long long ll; typedef pair<int,int> pii; const int N=10+10,INF=1e8; int n,mp[N][N], bmp[N][N][N]; int cnt[N], bcnt[N][N],vis[N][N]; struct node { int x, y, op; } ans[N]; bool check() { for (int i = 1; i <= 10; i++) if (cnt[i] == 1 || cnt[i] == 2) return 0; return 1; } void drop() { for (int i = 0; i < 5; i++) { int k = 0; for (int j = 0; j < 7; j++) if (mp[i][j]) mp[i][k++] = mp[i][j]; while (k < 7) mp[i][k++] = 0; } } bool remove() { int f=0; memset(vis, 0, sizeof vis); for (int x = 0; x < 5; x ++ ) { for (int y = 0; y < 7; y ++ ) if (mp[x][y]) { int l = x, r = x; while (l - 1 >= 0 && mp[l - 1][y] == mp[x][y]) l--; while (r + 1 < 5 && mp[r + 1][y] == mp[x][y]) r++; if (r - l + 1 >= 3) { f = 1; vis[x][y] = 1; } else { l = r = y; while (l - 1 >= 0 && mp[x][l - 1] == mp[x][y]) l--; while (r + 1 < 7 && mp[x][r + 1] == mp[x][y]) r++; if (r - l + 1 >= 3) { f = 1; vis[x][y] = 1; } } } } if (f) { for (int x = 0; x < 5; x ++ ) for (int y = 0; y < 7; y ++ ) if (vis[x][y]) { cnt[0] --; cnt[mp[x][y]] --; mp[x][y] = 0; } } return f; } void update() { while(1) { drop(); if(!remove()) break; } } bool dfs(int dep) { if (dep == n) return !cnt[0]; if(!check()) return 0; memcpy(bmp[dep], mp, sizeof mp); memcpy(bcnt[dep], cnt, sizeof cnt); for (int x = 0; x < 5; x ++ ) for (int y = 0; y < 7; y ++ ) if (mp[x][y]) { int xx = x + 1; if (xx < 5) { ans[dep] = { x, y, 1 }; swap(mp[x][y], mp[xx][y]); update(); if (dfs(dep + 1)) return 1; memcpy(mp, bmp[dep], sizeof mp); memcpy(cnt, bcnt[dep], sizeof cnt); } xx = x - 1; if (xx >= 0 && mp[xx][y]==0) { ans[dep] = { x, y, -1 }; swap(mp[x][y], mp[xx][y]); update(); if (dfs(dep + 1)) return 1; memcpy(mp, bmp[dep], sizeof mp); memcpy(cnt, bcnt[dep], sizeof cnt); } } return 0; } int main() { ios::sync_with_stdio(0); cin.tie(0); cin>>n; for (int i = 0; i < 5;i++) { int x,j=0; while(cin>>x&&x) { cnt[0]++; cnt[x]++; mp[i][j++] = x; } } if (dfs(0)) { for (int i = 0; i < n; i++) cout<<ans[i].x<<' '<<ans[i].y<<' '<< ans[i].op<<'\n'; } else cout << -1 << '\n'; return 0; }