HDU 5353 Average

参考博客:

https://blog.csdn.net/queuelovestack/article/details/47344537

和网上博客在对待1和2谁给谁的顺序上有些变化,从而如果输入数据刚开始全部相同,他的要特殊判断,而我这种不用。。

我的:

第一个尝试什么也不动的情况。

代码:

//I - Average
#include<stdio.h>
#include<string.h>
#define MAXN 100010
typedef long long LL;

int Data[MAXN];
int Try1[MAXN],Try2[MAXN];//枚举第一个人到第二个人的两种情况,还有一种就是不变,也就是初始化状态的Data[]
int op1[MAXN],op2[MAXN];
int n;
int cnt;
LL sum,aver;

void Init()
{
    for(int i=1;i<=n;i++)
    {
        Data[i]-=aver;
        Try1[i]-=aver;
        Try2[i]-=aver;
    }
}

bool Judge(int Arr[])
{
    int i;
    bool flag=true;

    for(i=2;i<=n;i++)
    {
        if(Arr[i]==-1)//向右边的拿一个
        {
            Arr[i]+=1;
            Arr[i%n+1]-=1;
            op1[cnt]=i%n+1;
            op2[cnt++]=i;
        }
        else if(Arr[i]==1)//多了一个,给右边一个
        {
            Arr[i]-=1;
            Arr[i%n+1]+=1;
            op1[cnt]=i;
            op2[cnt++]=i%n+1;
        }
        else if(Arr[i])
        {
            flag=false;
            break;
        }
    }
    if(!flag||Arr[1])
        return false;
    return true;
}

void Print(int Arr[])
{
    printf("%s\n","YES");
    printf("%d\n",cnt);
    for(int i=0;i<cnt;i++)
        printf("%d %d\n",op1[i],op2[i]);
}

int main()
{
    int i;
    int kase;

    scanf("%d",&kase);
    while(kase--)
    {
        memset(Data,0,sizeof(Data));
        memset(Try1,0,sizeof(Try1));
        memset(Try2,0,sizeof(Try2));
        sum=0;
        scanf("%d",&n);
        for(i=1;i<=n;i++)
        {
            scanf("%d",&Data[i]);
            sum+=Data[i];
            Try1[i]=Try2[i]=Data[i];
        }
        if(sum%n)
        {
            printf("%s\n","NO");
            continue;
        }
        aver=sum/n;
        Init();//预处理一下
        cnt=0;
        memset(op1,0,sizeof(op1));
        memset(op2,0,sizeof(op2));
        if(Judge(Data))//尝试一对二的第一种情况,就是什么都不动的
            Print(Data);
        else
        {
            memset(op1,0,sizeof(op1));
            memset(op2,0,sizeof(op2));
            Try1[1]+=1;//尝试第一个给第二个一颗糖果的情况
            Try1[2]-=1;
            op1[0]=2;
            op2[0]=1;
            cnt=1;
            if(Judge(Try1))
                Print(Try1);
            else
            {
                memset(op1,0,sizeof(op1));
                memset(op2,0,sizeof(op2));
                Try2[1]-=1;
                Try2[2]+=1;
                op1[0]=1;
                op2[0]=2;
                cnt=1;
                if(Judge(Try2))
                    Print(Try2);
                else
                    printf("%s\n","NO");
            }
        }
    }
    return 0;
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值