//O(n*n)的dp不会,水过,经验是:操作矩阵时候记录行坐标,列坐标很麻烦,可以新建一个x[MAX*MAX]的数组将需要的元素抽离出来 #include <iostream> #include <cstdio> #include <cstdlib> using namespace std; const int MAX=205,INF=1<<30; int mat[MAX][MAX]; int n; int zr[MAX*MAX],zc[MAX*MAX], nr[MAX*MAX],nc[MAX*MAX]; int ansr[MAX*MAX],ansc[MAX*MAX]; int f[MAX*MAX]; int zl,nl; bool eq[MAX*MAX]; int main(){ //freopen("i.txt","r",stdin); //freopen("e://t1.txt","w",stdout); int dis; zl=nl=0; scanf("%d",&n); int t; for(int i=0;i<n;i++){ for(int j=0;j<n;j++){ scanf("%d",&t); mat[i][j]=t; if(t){ nr[nl]=i; nc[nl]=j; ++nl; } else{ zr[zl]=i; zc[zl]=j; f[zl]=INF; ansr[zl]=INF; ansc[zl]=INF; ++zl; } } } for(int i=0;i<nl;i++){ for(int j=0;j<zl;j++){ dis=abs(nr[i]-zr[j])+ abs(nc[i]-zc[j]); if(dis==f[j]&& (ansr[j]!=nr[i]||ansc[j]!=nc[i])){ eq[j]=false; } else if(dis<f[j]){ eq[j]=true; f[j]=dis; ansr[j]=nr[i]; ansc[j]=nc[i]; } } } // for(int i=0;i<n;i++){ // for(int j=0;j<n;j++) // cout<<mat[i][j]<<" "; // cout<<endl; // } nl=zl=0; for(int i=0;i<n;i++){ for(int j=0;j<n;j++){ if(j) cout<<" "; if(mat[i][j]) cout<<mat[i][j]; else{ if(eq[zl]) cout<<mat[ansr[zl]][ansc[zl]]; else cout<<0; ++zl; } } cout<<endl; } }