题意:有两种操作:合并两个相邻的数;把一个数拆分成两部分。
给出n个数,用上面的两种操作,将这组数分成k组相同的数。输出最小的操作次数,不能完成输出-1.
思路:先判断这组数是否能整除K,不能就输出-1。能,tmp=sum/k,从1-n对每个数进行以下操作:ai<tmp,就向后面的数取自己缺的部分,ai>tmp就以tmp为单位拆分。中间的细节操作看代码吧。
代码写出来一直错。试了一百组样例,想哭。||||||居然是把"%lld改成%I64d"就对了,以后还是不要用lld了。。
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
typedef long long ll;
//#define ll __int64
int a[maxn];
int main()
{
int t,n,r=1;
ll k;
scanf("%d",&t);
while(t--)
{
scanf("%d%I64d",&n,&k);
ll head;
ll sum=0;
for(int i=1;i<=n;i++)
{
scanf("%I64d",&a[i]);
sum+=a[i];
}
if(sum%k)
{
printf("Case #%d: -1\n",r++);
continue;
}
ll tmp=sum/k;
ll cnt=0;
ll rear=0;
for(int i=1;i<=n;i++)
{
head=tmp-rear;//前面那个数还差多少
if(a[i]>head)
{
if(head)cnt++;//与当前拆开
if(i!=1&&head) cnt++;//与前一个合
cnt+=((a[i]-head)%tmp==0?(a[i]-head)/tmp-1:(a[i]-head)/tmp);
rear=((a[i]-head)%tmp==0?tmp:(a[i]-head)%tmp);
}
else//不足以或者刚好补足前面的
{
if(rear!=0)cnt++;
rear=a[i]+rear;
}
}
printf("Case #%d: %I64d\n",r++,cnt);
}
}