数组前缀和思想:
二维数组不好直接统计,输入时先记录每一行,每一列,输出结束再次按行按列统计前缀和:
#include<bits/stdc++.h> using namespace std; int n; int a[120][120]; int ans; const int inf=1e9; int x[120],xsum[120]; int y[120],ysum[120]; int xN[120],yN[120]; int xsn[120],ysn[120]; int main() { scanf("%d",&n); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++){ scanf("%d",&a[i][j]); if(a[i][j]){ xN[i]++,yN[j]++; xsn[i]+=i,ysn[j]+=j; } } //按行按列统计个数与前缀和; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++){ x[i]=x[i-1]+xN[i]; y[j]=y[j-1]+yN[j]; xsum[i]=xsum[i-1]+xsn[i]; ysum[j]=ysum[j-1]+ysn[j]; } //枚举空白点; int flag = 0; ans = inf; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++){ if(a[i][j]==0){ flag=1; int xs = x[i-1]*i - xsum[i-1] + xsum[n]-xsum[i]-(x[n]-x[i])*i; int ys = y[j-1]*j - ysum[j-1] + ysum[n]-ysum[j]-(y[n]-y[j])*j; ans=min(ans,xs+ys); } } if(flag)cout<<ans<<endl; else cout<<-1<<endl; return 0; }