2020ICPC·小米 網路選拔賽第一場 J.Matrix Subtraction (貪心,二維差分)
阿新 • • 發佈:2020-10-26
-
題意:給一個\(nXm\)的矩陣,可以選取\(aXb\)的子矩陣,使子矩陣中的所有元素減一,問最後是否能使矩陣中所有元素變為\(0\).
-
題解:首先貪心,我們看最左上角的元素,如果\(g[1][1]\ge0\),那麼我們就要對其子矩陣的所有元素減去\(g[1][1]\),然後因為\(g[1][1]\)已經是\(0\)了,假如\(g[1][2]\)存在的話,我們就只能讓它成為子矩陣的左上角然後再對所有子矩陣減去\(g[1][2]\),以此類推,但是直接暴力的話複雜度會炸,我們需要用資料結構來維護,直接用二維差分即可,每次列舉到某個元素的時候判斷它是否不小於\(0\),如果不是就不合法.
-
程式碼
int t; int n,m,a,b; int g[1010][1010]; int p[1010][1010]; void updata(int i,int j,int ii,int jj,int c){ p[i][j]+=c; p[ii+1][j]-=c; p[i][jj+1]-=c; p[ii+1][jj+1]+=c; } void solve(){ n=read(),m=read(),a=read(),b=read(); for(int i=1;i<=n;++i){ for(int j=1;j<=m;++j){ g[i][j]=read(); p[i][j]=g[i][j]-g[i-1][j]-g[i][j-1]+g[i-1][j-1]; } } for(int i=1;i<=n;++i){ for(int j=1;j<=m;++j){ p[i][j]=p[i][j]+p[i-1][j]+p[i][j-1]-p[i-1][j-1]; if(p[i][j]<0){ puts("QAQ"); return; } else if(p[i][j]>0){ if(i+a-1>n || j+b-1>m){ puts("QAQ"); return; } else updata(i,j,i+a-1,j+b-1,-p[i][j]); } } } puts("^_^"); } int main() { //ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); t=read(); while(t--){ solve(); } return 0; }