数组前缀和思想:
二维数组不好直接统计,输入时先记录每一行,每一列,输出结束再次按行按列统计前缀和:
#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;
}
京公网安备 11010502036488号