T2 調了 1h 沒調出來,丟了一坨沒分的shi扔了。
我想放一下作為開頭:
include <bits/stdc++.h> #define int long long using namespace std; inline int read() { int w=1,s=0;char ch=getchar(); while(!isdigit(ch)){if(ch'-')w=-1;ch=getchar();} while(isdigit(ch)){s=s10+(ch-'0');ch=getchar();} return ws; } const int mod=998244353; const int maxn=3e3+10; const int inf=1e9+7; int n,m; char a[maxn][maxn]; bool hang[maxn],lie[maxn]; bool f[maxn][maxn]; map<string,int> mp; int dfs() { bool can=1; for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)if(!f[i][j]){can=0;break;} if(can){return 0;} string s; for(int i=1;i<=n;i++)for(int j=1;j<=m;j++) { if(f[i][j])s=s+'W'; else s=s+a[i][j]; } if(mp[s])return mp[s]; vector hangr,hangb,lier,lieb; for(int i=1;i<=n;i++) { if(hang[i])continue; bool r=1; for(int j=1;j<=m;j++)if(a[i][j]'B'&&!f[i][j]){r=0;break;} if(r)hangr.push_back(i); } for(int i=1;i<=n;i++) { if(hang[i])continue; bool b=1; for(int j=1;j<=m;j++)if(a[i][j]'R'&&!f[i][j]){b=0;break;} if(b)hangb.push_back(i); } for(int i=1;i<=m;i++) { if(lie[i])continue; bool r=1; for(int j=1;j<=n;j++)if(a[j][i]'B'&&!f[j][i]){r=0;break;} if(r)lier.push_back(i); } for(int i=1;i<=m;i++) { if(lie[i])continue; bool b=1; for(int j=1;j<=n;j++)if(a[j][i]'R'&&!f[j][i]){b=0;break;} if(b)lieb.push_back(i); } int res=inf; for(auto i : hangr) { for(int j=1;j<=m;j++) { f[i][j]=1; } hang[i]=1; res=min(res,dfs()+1); for(int j=1;j<=m;j++) { f[i][j]=0; } hang[i]=0; } for(auto i : hangb) { for(int j=1;j<=m;j++) { f[i][j]=1; } hang[i]=1; res=min(res,dfs()+1); for(int j=1;j<=m;j++) { f[i][j]=0; } hang[i]=0; } for(auto i : lier) { for(int j=1;j<=n;j++) { f[j][i]=1; } lie[i]=1; res=min(res,dfs()+1); for(int j=1;j<=n;j++) { f[j][i]=0; } lie[i]=0; } for(auto i : lieb) { for(int j=1;j<=n;j++) { f[j][i]=1; } lie[i]=1; res=min(res,dfs()+1); for(int j=1;j<=n;j++) { f[j][i]=0; } lie[i]=0; } return mp[s]=res; } void Sub1() { int ans=inf; mp.clear(); for(int i=1;i<=n;i++)hang[i]=0; for(int j=1;j<=m;j++)lie[j]=0; for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)f[i][j]=0; ans=dfs(); printf("%lld\n",(ansinf?-1:ans)); } void Main() { n=read(),m=read(); for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { cin>>a[i][j]; } } bool f=0; for(int i=1;i<=n;i++){bool ff=1;for(int j=2;j<=m;j++)if(a[i][j]!=a[i][j-1]){ff=0;break;}if(ff)f=1;break;} for(int i=2;i<=m;i++){bool ff=1;for(int j=1;j<=n;j++)if(a[j][i]!=a[j][i-1]){ff=0;break;}if(ff)f=1;break;} if(!f){puts("-1");return ;} Sub1(); } signed main() { #ifdef Lydic freopen(".in", "r", stdin); freopen(".out", "w", stdout); // #else // freopen("mst.in", "r", stdin); // freopen("mst.out", "w", stdout); #endif int T=read(); while(T--)Main(); return 0; }
好了,開始寫總結。
賽時
開題,先看 T1。
暴力一開始寫掛了,所以直接去想正解(因為這時候一車人過了)。
簡單思考發現最終相等的值是唯一的,所以容易想到去構造一中最少的修改方案。
有一種線性的貪心構造,寫完以後發現過了大樣例,但是想到之前大樣例全過但是真實資料一分沒有的經歷,我弱弱的放棄了。
捨棄一下正解,胡一個穩定 \(\mathcal{O}(n^2)\) 的 DP,胡完以後看看提交記錄,發現 AKIG 叕 AK 了,我大驚。
寫出來以後發現沒掛,於是開始考慮用什麼資料結構去最佳化。
但是我賽時一直傻傻地盯著 DP 的內層迴圈去找資料結構最佳化,絲毫沒發現我剛剛的貪心是正解。
到最後也沒出來,然後最終得分 60pts。
T2 的話看不出來什麼東西,想先寫一下暴力,然後就有了上面的一大坨東西。
T3 的話感覺是一個很可做的資料結構計數問題,暴力思路很好想,然後紙上推推畫畫,隨便用樹狀陣列最佳化一下,就莫名其妙地過掉了大樣例。賽時感覺比 T1 簡單。(我猜某雞不會看這篇文章,所以在這裡口嗨一下它的 T3:\(\Large \color{red}{菜}\))
T4 看了一眼,感覺 T2 的分可以拿到,所以決定死盯 T2,然後到最後也沒盯出來,使得最基本的暴力分數也沒拿到。
賽後
發現我是為數不多過 T3 但是沒過 T1 的人,我太菜了。
一聽別人的思路就會 T1 了,花了不到 5min 就過了。我更菜了。
現在在訂 T2,努力在下個國慶節日期是完全平方數之前訂出來(3026.10.01)。
最近的比賽時間不夠的問題逐漸顯現出來,可能是賽時寫的不夠勤,沒做到有分就寫。
導致我最後 20min 鍵盤都快敲出火了。
寫完了,溜了。