zoukankan      html  css  js  c++  java
  • 2015多校第6场 HDU 5353 Average 贪心,细节处理

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5353

    题意:有n个人围城一个环,每一个人手里都有一些糖果,第i个人有ai块。现在有三种操作:第i个人给第i+1个人一块。第i+1个人给第i个人一块。什么都不做。第i个人和第i+1个人之间,可以选择一种操作并执行,问最终能不能让所有人手里的糖相等。

    解法:贪心。

    当n = 1 时,永远是YES

    当n = 2 时,注意1和2之间只能有一种操作,不存在循环。

    当n > 2 时:

    糖的总数不能均分到n个人手中,直接NO

    可以分开,存在一个循环,那么枚举第1个人对第2个人的操作,那么对于第2个人及以后的人来说它的左侧已经确定了,那么它为了维护自己的糖数是平均值,只能对下一个人进行操作,如果当前比平均值少1,那么从下一个人手里拿一个,如果正好,那么不操作,如果多一个,那么给下面的人一个,其他情况都是无解的。

    注意:在操作时,要保证它当前有糖。所以要判断一下。

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 1e5+6;
    typedef long long LL;
    int a[maxn], ans[maxn];
    
    int main()
    {
        int T, n;
        scanf("%d", &T);
        while(T--)
        {
            scanf("%d", &n);
            LL sum = 0, ave = 0;
            for(int i=0; i<n; i++){
                scanf("%d", &a[i]);
                sum += a[i];
            }
            bool flag = 1;
            int num;
            ave = sum/n;
            memset(ans, 0, sizeof(ans));
            if(sum%n){
                flag = 0;
            }
            else if(n == 2){
                if(abs(a[0]-ave) >= 2) flag = 0;
                else if(abs(a[0]-ave)){
                    ans[0]=a[0]>a[1]?1:-1;
                }
            }
            else if(n>2){
                int i,j,k;
                for(i=-1; i<=1; i++){
                    ans[0]=i;
                    for(j=1; j<n; j++){
                        k=a[j]+ans[j-1];
                        if(k==ave) ans[j]=0;
                        else if(k+1==ave){
                            if(a[(j+1)%n]) ans[j]=-1;
                            else break;
                        }
                        else if(k-1==ave){
                            ans[j]=1;
                        }
                        else break;
                    }
                    if(j==n&&a[0]-ans[0]+ans[n-1]==ave) break;
                }
                if(i==2) flag = 0;
            }
            if(flag==0){
                puts("NO");
            }
            else{
                puts("YES");
                num = 0;
                for(int i=0; i<n; i++) if(ans[i]) num++;
                printf("%d
    ", num);
                for(int i=0; i<n; i++){
                    if(!ans[i]) continue;
                    int u = i+1;
                    int v = (i+1)%n+1;
                    if(ans[i]==-1) swap(u, v);
                    printf("%d %d
    ", u, v);
                }
            }
        }
        return 0;
    }
    
  • 相关阅读:
    课堂练习
    日程管理测试用例
    日程管理APP的测试计划和测试矩阵
    日程管理Bug Report
    图书管理系统活动图
    团队如何做决定?
    课堂练习
    课堂练习(NABCD Model)
    课堂练习
    日程管理的测试计划和测试矩阵
  • 原文地址:https://www.cnblogs.com/spfa/p/7337673.html
Copyright © 2011-2022 走看看