CodeForces - 1255E1

E1. Send Boxes to Alice (Easy Version)

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.

Examples
input
3
1 0 1
output
2
input
1
1
output
-1

题意:
一串01序列,一个位置上的1可以移动到相邻的两个位置上,问最少多少次移动可以使这串序列的GCD大于1。
先数出这段序列中1的个数,如果个数小于2,则无解,然后根据1的个数,可以判断这段序列的最终GCD为1的个数的因子,然后依次判断因子,找到最小的答案。
关于如何移动数字,贪心,响铃的x个移动到同一位置即可,相邻的数字移动到他们的中间位置是最优解,关于这个问题,ACWing中的一道货仓选址问题中有视频详细解释。

#include<stdio.h>
#include<math.h>
#include<vector>
using namespace std;
typedef long long ll;
vector<int>v;
int n,m=0;
ll solve(int x) {
	int mid=x>>1;
	ll ans=0;
	for(int i=0; i<v.size();i+=x) {
		for(int j=0;j<x;++j){
			ans+=abs(v[i+j]-v[i+mid]);
		}
	}
	return ans;
}
int main() {
	scanf("%d",&n);
	for(int i=1; i<=n; ++i) {
		int x;
		scanf("%d",&x);
		if(x) {
			m++;
			v.push_back(i);
		}
	}
	if(m<2) {
		printf("-1\n");
		return 0;
	}
	ll ans=2e18;
	for(int i=2; i<=m; ++i) {
		if(m%i==0) {
			ans=min(ans,solve(i));
		}
	}
	printf("%lld\n",ans);
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值