HDU5353 ※贪心

Sample Input
3 6 1 0 1 0 0 0 5 1 1 1 1 1 3 1 2 3
Sample Output
NO YES 0 YES 2 2 1 3 2

题目大意

条件
1,2,3,…,n 个人围成一圈,每个人都有糖果。
每两个人之间只能经行三种操作,每种操作只能经行一次

  1. a给b一颗糖,如果a有糖
  2. b给a一颗糖,如果b有糖
  3. a,b之间不进行交换

求解
经过一系列操作,是否能平分糖果,否输出“NO”,是输出”YES”\n最少操作数\n如何操作

解题-贪心

AC代码

#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<cstdio>
#define N 100005 
using namespace std;
int s[N],s1[N],s2[N],n,m;
int i;
struct oper{//x->y
    int x;
    int y;
}op[N];
bool fun(int *s){
    for(i=2;i<=n;i++)
        if(s[i]==1){
            s[i%n+1]++;
            op[m].x=i;op[m].y=i%n+1;
            m++;
        }
        else if(s[i]==-1){
            s[i%n+1]--;
            op[m].x=i%n+1;op[m].y=i;
            m++;
        }
        else if(s[i]!=0)
            break;
    if(i<=n||s[1])
        return false;
    return true;
}
void clear(){
    for(i=0;i<N;i++){
        op[i].x=op[i].y=0;
        m=0;
    }
}
bool all_same(){
    for(i=1;i<=n;i++)
        if(s[i]!=s[1])
            return false;
    return true;
}
int main(){
    ios::sync_with_stdio(false);
    int t;
    long long sum,aver;
    bool flag;
    cin>>t;
    while(t--){
        sum=0;flag=false;
        cin>>n;
        for(i=1;i<=n;i++){
            cin>>s[i];
            sum+=s[i];
        }
        if(sum%n){
            puts("NO");
            continue;
        }
        if(all_same()){
            puts("YES\n0");
            continue;
        }
        aver=sum/n;
        for(i=1;i<=n;i++){
            s[i]-=aver;s1[i]=s2[i]=s[i];
            if(s[i]<-2||s[i]>2)
                break;
        }
        if(i<=n){
            puts("NO");
            continue;
        }
        clear();
        s1[1]--;s1[2]++;
        op[0].x=1;op[0].y=2;m=1;
        if(!fun(s1)){
            clear();
            s2[1]++;s2[2]--;
            op[0].x=2;op[0].y=1;m=1;
        }
        else
            flag=true;
        if(!flag){
            if(!fun(s2))    
                clear();
            else
                flag=true;
        }
        if(!flag)
            if(fun(s))
                flag=true;
        if(flag){
            puts("YES");
            cout<<m<<endl;
            for(i=0;i<m;i++){
                cout<<op[i].x<<" "<<op[i].y<<endl;
            }
        }
        else
            puts("NO");
    }
    return 0;
}

参考资料

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

猜你喜欢

转载自blog.csdn.net/weixin_42946476/article/details/81623481