题目:
题目大意:
输入n,代表n个盒子,然后输入n个数字ai, ai为0或1, 1代表有糖果,0代表没有糖果。糖果可以进行左右移动(每次移动一格且消耗一秒的时间),移动后每个格子的糖果数必须为k的倍数(k > 1)。求h花费的最短时间。
解题思路:
要求为k的倍数,可以先求糖果的总数,然后进行循环判断,要为k的倍数,那么就要使 num % k == 0。(num 为糖果总数)因此,要话费时间最短,所以 k 个糖果为一组,这样话费最小。我们输入ai,记录是否为1,如果为1,记录当前的位置。对于每一组 k ,通过画图可得知两边糖果都移动到最中间花费的时间最短。因此对每次 k 进行处理计算话费时间,最后通过比较选出最小值。
代码:
#include <iostream>
#include <cstdio>
#include <vector>
#include <cmath>
using namespace std;
vector <int> res;
long long solve(int x){
long long result = 0;
int m = x / 2;
for (int i = 0; i < res.size();){
vector <int> temp;
for (int j = 0; j < x; j ++){
temp.push_back(res[i+j]);
}
for (int j = 0; j < x; j ++){
result += abs(temp[j] - temp[m]);
}
i += x;
}
return result;
}
int main(){
int n,k;
scanf("%d",&n);
for (int i = 1 ; i <= n; i++){
scanf("%d",&k);
if (k == 1){
res.push_back(i);
}
}
int num = res.size();
if (num <= 1){
printf("-1\n");
return 0;
}
long long result = solve(num);
for (int i = 2; i <= num; i++){
if (num % i == 0){
result = min(result,solve(i));
}
}
printf("%lld\n",result);
return 0;
}