2015 Multi-University Training Contest 6(HDOJ5353)

官方题解:http://bestcoder.hdu.edu.cn/blog/


HDOJ5355、5360、5363超过300人AC,思路见官方题解

比赛时5353一直WA,2小时后发现队友5360居然还没做出来,orz,于是花了20+分钟把这题1Y

5355比赛SPJ写错,基本大家不CE,都能AC


HDOJ5353

题意:有n个人坐成一圈,每人有m个糖果,每对相邻的人可以进行一次给一个糖果的操作,问能否均分糖果,能的话输出所有操作,x给y一个糖果

思路:先把不能整除的情况特判掉,再把所有数扣掉平均数方便后面操作,特判n<3的情况,最后再开始处理一般情况。

每对相邻的人一共三种情况:给、不变、拿,暴力第一对人的所以情况,之后后面每一对人的操作也就确定了

注意:全为0的情况,要输出YES 0,就因为这个一直WA。。。原先代码是先算fun(-1)再算fun(0)。。。。调换位置就AC了

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <vector>
using namespace std;
typedef long long LL;
const int MAXN=1e5+10;

int T,n,m,k;
int a[MAXN],b[MAXN],f[MAXN];
LL sum;
int avg;
void init(){
    sum=0;
    for(int i=0;i<n;i++){
        scanf("%d",&a[i]);
        sum+=a[i];
    }
    a[n]=a[0];
}

void print(){
    printf("YES\n");
    int p=0;
    for(int i=0;i<n;i++){
        if(f[i]!=0)p++;
    }
    printf("%d\n",p);
    for(int i=0;i<n-1;i++){
        if(f[i]==-1){
            printf("%d %d\n",i+1,i+2);
        }
        if(f[i]==1){
            printf("%d %d\n",i+2,i+1);
        }
    }
    if(f[n-1]==-1){
        printf("%d 1\n",n);
    }
    if(f[n-1]==1){
        printf("1 %d\n",n);
    }
}

bool fun(int x){
    memset(f,0,sizeof(f));
    for(int i=0;i<=n;i++){
        b[i]=a[i];
    }

    f[0]=x;
    b[1]-=f[0];
    b[0]+=f[0];
    b[n]=b[0];
    for(int i=1;i<n;i++){
        if(abs(b[i])>=2)return 0;
        if(b[i]==1){
            f[i]=-1;
        }else if(b[i]==-1){
            f[i]=1;
        }
        b[i+1]-=f[i];
        b[i]+=f[i];
    }
    for(int i=1;i<=n;i++){
        if(b[i]!=0)return 0;
    }
    return 1;
}

void work(){
    if(fun(0)){print();return;}
    if(fun(-1)){print();return;}
    if(fun(1)){print();return;}
    printf("NO\n");
    return;
}

int main(){
#ifdef DEBUG
   freopen("CBin.txt","r",stdin);
   //freopen("CBout.txt","w",stdout);
#endif
    scanf("%d",&T);
    while(T--){
        scanf("%d",&n);
        init();
        if(sum%n!=0){
            printf("NO\n");
            continue;
        }
        avg=sum/n;
        for(int i=0;i<n;i++){
            a[i]-=avg;
        }
        a[n]=a[0];
        if(n==2||n==1){
            if(fun(0))print();
            else printf("NO\n");
        }else
            work();
    }
    return 0;
}


你可能感兴趣的:(2015 Multi-University Training Contest 6(HDOJ5353))