题目: This is the easier version of the problem. In this version, 1≤n≤105 and 0≤ai≤1. You can hack this problem only if you solve and lock both problems.
Christmas is coming, and our protagonist, Bob, is preparing a spectacular present for his long-time best friend Alice. This year, he decides to prepare n boxes of chocolate, numbered from 1 to n. Initially, the i-th box contains ai chocolate pieces.
Since Bob is a typical nice guy, he will not send Alice n empty boxes. In other words, at least one of a1,a2,…,an is positive. Since Alice dislikes coprime sets, she will be happy only if there exists some integer k>1 such that the number of pieces in each box is divisible by k. Note that Alice won’t mind if there exists some empty boxes.
Charlie, Alice’s boyfriend, also is Bob’s second best friend, so he decides to help Bob by rearranging the chocolate pieces. In one second, Charlie can pick up a piece in box i and put it into either box i−1 or box i+1 (if such boxes exist). Of course, he wants to help his friend as quickly as possible. Therefore, he asks you to calculate the minimum number of seconds he would need to make Alice happy.
Input
The first line contains a single integer n (1≤n≤105) — the number of chocolate boxes.
The second line contains n integers a1,a2,…,an (0≤ai≤1) — the number of chocolate pieces in the i-th box.
It is guaranteed that at least one of a1,a2,…,an is positive.
Output
If there is no way for Charlie to make Alice happy, print −1.
Otherwise, print a single integer x — the minimum number of seconds for Charlie to help Bob make Alice happy.
Hard Version在这
即n个盒子,其中m个盒子有一个糖果。通过移动(1S可以把一个糖果移动到前后盒子),使得每个盒子糖果数是K的整数倍。
枚举K,K是m因子,可以sqrt(m)枚举,K确定后模拟。
首先贪心思想,肯定每相邻k个组成一组(每凑k个再开始下一组),否则不划算。
对于每一组,显然移到中间比较好(k为偶数,中间两个都一样)。这个可以画图证明,中间往右往左都变大。
#include
#include
#include
#include
using namespace std;
int a[100100];
vector<int> g;
typedef long long LL;
LL calc(int x) {
//cout << x;
LL ans = 0;
for (int s = 0; s < g.size(); ) {
vector<int> tmp;
for (int j = 0; j < x; j++) tmp.push_back(g[s+j]);
int md = x / 2;
//cout << md;
for (int j = 0; j < x; j++) {
// cout << tmp[j] << " " << tmp[md] << "\n";
ans = ans + abs(tmp[md] - tmp[j]);
}
s = s + x;
}
return ans;
}
int main() {
int n;
// n = 100000;
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> a[i];
if (a[i] == 1)
//if(i<=3||i==99999)
g.push_back(i);
}
int m = g.size();
if (m <= 1) {
puts("-1");
return 0;
}
LL ans = calc(m);
for (int i = 2; i <= sqrt(m); i++)
if (m % i == 0) {
ans = min(ans,min(calc(i),calc(m/i)));
}
cout << ans;
return 0;
}