1. 程式人生 > >Codeforces 838A - Binary Blocks(二維前綴和+容斥)

Codeforces 838A - Binary Blocks(二維前綴和+容斥)

using min class blank -i push_back cin size 1的個數

838A - Binary Blocks

思路:求一下前綴和,然後就能很快算出每一小正方塊中1的個數了,0的個數等於k*k減去1的個數,兩個的最小值就是要加進答案的值。

代碼:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pb push_back
#define mem(a,b) memset((a),(b),sizeof(a))
const int INF=0x3f3f3f3f;
const int N=5000;
char mp[N][N];
int Mp[N][N]={0};

int
main() { ios::sync_with_stdio(false); cin.tie(0); int n,m; cin>>n>>m; for(int i=1;i<=n;i++)cin>>mp[i]+1; for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) Mp[i][j]=mp[i][j]-0; } for(int i=1;i<N;i++) { for(int j=1
;j<N;j++) { Mp[i][j]+=Mp[i-1][j]+Mp[i][j-1]-Mp[i-1][j-1]; } } int minn=min(n,m); int ans=INF; for(int i=2;i<=minn;i++) { bool flag=true; int x=n/i; int y=m/i; if(n%i)x++; if(m%i)y++; int cnt=0;
for(int j=1;j<=x;j++) { for(int k=1;k<=y;k++) { if(j==1&&k==1) { int t=Mp[j*i][k*i]; cnt+=min(i*i-t,t); } else { int t=Mp[j*i][k*i]+Mp[j*i-i][k*i-i]-Mp[j*i][k*i-i]-Mp[j*i-i][k*i]; cnt+=min(i*i-t,t); } } } ans=min(ans,cnt); } printf("%d\n",ans); return 0; }

Codeforces 838A - Binary Blocks(二維前綴和+容斥)