IndiaHacks 2nd Elimination 2017A. Binary Blocks
https://codeforces.com/contest/838/problem/A
二维前缀和的应用,注意可能比较绕
然后注意边界可以拿min的替换就行
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<vector>
#include<algorithm>
#include<math.h>
#include<sstream>
#include<string>
#include<string.h>
#include<iomanip>
#include<stdlib.h>
#include<map>
#include<queue>
#include<limits.h>
#include<climits>
#include<fstream>
#include<stack>
using namespace std;
typedef long long ll;
ll mp[2510][2510];
bool is_prime(ll x)
{
for (ll a = 2; a * a <= x; a++)
if (x % a == 0)
return false;
return true;
}
int main()
{
ll n, m; cin >> n >> m; cin.get();
string s;
for (int i = 0; i < n; i++)
{
getline(cin, s);
for (int j = 0; j < m; j++)
{
mp[i + 1][j + 1] = s[j] - '0';
}
}
//前缀和
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
{
mp[i][j] += mp[i - 1][j] + mp[i][j - 1] - mp[i - 1][j - 1];
}
}
queue<ll>qu_pri;
qu_pri.push(2);
for (ll i = 3; i <= min(n, m); i += 2)
if (is_prime(i))
qu_pri.push(i);
ll ans = LLONG_MAX;
while (!qu_pri.empty())
{
ll now = qu_pri.front(); qu_pri.pop();
ll ans_tmp = 0;
for (ll i = 1; (i - 1) * now < n; i++)
{
for (ll j = 1; (j - 1) * now < m; j++)
{
ll tg = mp[min(i * now, n)][min(j * now, m)]
+ mp[(i - 1) * now][(j - 1) * now]
- mp[min(i * now, n)][(j - 1) * now]
- mp[(i - 1) * now][min(j * now, m)];
ans_tmp = ans_tmp +min(tg,now*now-tg);
}
}
ans = min(ans, ans_tmp);
}
cout << ans;
return 0;
}