第13届 广东工业大学ACM程序设计大赛 C题 平分游戏

题目描述

转眼间又过了一年,又有一届的师兄师姐要毕业了。

​ 有些师兄师姐就去了景驰科技实习。 在景驰,员工是他们最宝贵的财富。只有把每一个人的专业性和独特性结合在一起,他们才会获得成功。他们致力于为所有员工打造一个能够被激励,并分享公司成功的工作环境。
创新精神:为了改变人类出行而不断迎接全新挑战。
团队协作:依靠集体的智慧,坦诚无私地帮助彼此。
结果导向:在所有方面都力争做到中国第一和世界一流,并对结果负责。
共同成长:学习永无止境,通过个人发展和职业成长实现成就。
GUDTACM集训队教练孙壕又来请大家大搓一顿。

茶余饭足以后,有人提议不如来玩游戏吧。狼人杀谁是卧底跳一跳都已经玩得太多了,所以大家决定玩一个更加有挑战性的游戏。

集训队一共有n位同学,他们都按照编号顺序坐在一个圆桌旁。第i位同学一开始有a[i]个硬币,他们希望使得每位同学手上的硬币变成相同的数目。每一秒钟,有且仅有一位同学可以把自己手上的一枚硬币交给另一位同学,其中这两位同学中间必须间隔k位同学。

现在问的是最少几秒后所有同学手上的有相同数量的硬币

输入描述:

第一行输入两个整数n,k(1<=n<=1000000,0<=k<=n)
接下来的一行有n个整数,第i个整数a[i](0<=a[i]<=1e9)表示第i位同学手上的硬币的数量。

输出描述:

一个整数,表示最少几秒后所有同学手上的有相同数量的硬币。如果不可能,则输出gg。

示例1

输入

5 0
2 3 1 5 4

输出

3

emmmmm……超时了

#include <stdio.h>
#include <stdlib.h>
#include<string.h>
#define N 1000010
long long  dp[N] = {0};
void quickSort(int left,int right)
{
    if(left < right )
    {
        int i=left;
        int j=right;
        int key=dp[left];
        while(i < j)
        {
            while(i < j && key <= dp[j])
            {
                j--;
            }
            if(i < j ) dp[i] = dp[j];
            while(i < j && key > dp[i])
            {
                i++;
            }
            if(i < j ) dp[j] = dp[i];

        }
        dp[i] = key;
        quickSort(left,i-1);
        quickSort(i+1,right);
    }
}

int main()
{
    int n,k;
    int a[N];
    int index1[N] = {0};

    scanf("%d %d",&n,&k);
    int i,j;
    k = k < n ? k : n;
    long long sum=0;
    for(i = 0; i < n; i++)
    {
        scanf("%d",&a[i]);
        sum+=a[i];
    }

    if(sum % n != 0)
    {
        printf("gg\n");
        return 0;
    }
    long long avg = sum/n;
    long long ans =0;
    for(i = 0; i < n; i++)
    {
        if(!index1[i])
        {
            j = i;
            int cnt = 0;
            long long p = 0,tmp = 0;
            while(!index1[j])
            {
                index1[j] =1;
                dp[cnt] = a[j]-avg+p;//送出去的硬币
                tmp+=a[j];//一圈硬币的总数
                p=dp[cnt++];//上一个孩子送出去的硬币;
                j=(j+k+1)%n;
            }
            //判断这一圈的硬币是否能被整除
            if(tmp % cnt != 0 || tmp/cnt !=avg)
            {
                printf("gg\n");
                return 0;
            }
            quickSort(0,cnt-1);
            long long  min = dp[cnt/2];
            int z;
            for(z = 0; z < cnt; z++   )
                ans+= abs(min-dp[z]) ;
        }
    }
    printf("%lld\n",ans);
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值