标签:
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 2069 Accepted Submission(s): 517
Special Judge
题目大意:有n个人围成一圈,每个人手上都有一定数量的糖果,相邻两个人可是给一个糖果,但是只能给一次,如x,y。x可以给y一个糖果,或者y可以给x一个糖果。也可以不操作,即都不给糖果。第一个人可以给第n个人一个糖果,或者第n个人给第一个人一个糖果,或不给。问是否可以通过给糖果这样的操作,让所有的人手中的糖果数量相同。如果可以,输出YES和需要多少次,同时输出路径。否则输出NO。
解题思路:枚举第一个人对第二个人的三种操作,然后看第二个人跟average的差值,如果是-1,那么第二个人从第三个人手中拿走一个糖果,如果是1,那么第二个人给第三个人一个糖果,如果为零,则不操作。依次遍历到n。因为第n个人跟第1个人是可以操作的,所以我在操作第n个的时候,把对第一个人的操作放在了n+1的位置,c[1]+=c[n+1]判断第一个人的结果是否为零,如果为零,这说明可以,否则不可以。
#include<stdio.h> #include<algorithm> #include<string.h> using namespace std; const int maxn=1e5+200; typedef long long INT; int a[maxn] ,b[maxn] ,c[maxn]; int f[3]={0,1,-1}; int abs(int x){ return x>0? x: -x; } struct Oper{ int x,y; }oper[maxn]; int main(){ int t,n; scanf("%d",&t); while(t--){ scanf("%d",&n); INT sum=0; for(int i=1;i<=n;i++){ scanf("%d",&a[i]); sum+=a[i]; } if(sum%n!=0){ printf("NO\n");continue; }else{ if(n==1){ //1个的时候必然YES printf("YES\n0\n"); continue; } if(n==2){ //特判两个的情况 if(a[1]-a[2]==2){ printf("YES\n1\n"); printf("1 2\n"); continue; }else if(a[1]-a[2]==-2){ printf("YES\n1\n"); printf("2 1\n");continue; }else if(a[1]==a[2]){ printf("YES\n"); printf("0\n");continue; } } const int ave=sum/n; int flag=0; for(int i=1;i<=n;i++){ b[i]=a[i]-ave; //把跟平均数的差值放在b数组中 if(abs(b[i])>2){ printf("NO\n"); flag=1; break; } } if(flag) continue; int num; b[n+1]=0; for(int k=0;k<3;k++){ num=0; //num放错位置,wa了 for(int i=1;i<=n+1;i++){ c[i]=b[i]; } if(f[k]==1){ oper[num].x=2; oper[num++].y=1; }else if(f[k]== -1){ oper[num].x=1; oper[num++].y=2; } //每次对c数组操作 c[1]+=f[k]; if(abs(c[1])>1 ){ continue; } c[2]-=f[k]; if(abs(c[2])>1){ continue; } int mark=0; for(int i=2;i<=n;i++){ //遍历2-->n if(c[i]==1){ c[i]-=1; c[i+1]+=1; if(i<n){ oper[num].x=i; oper[num++].y=i+1; }else{ oper[num].x=n; oper[num++].y=1; } }else if(c[i]==-1){ c[i]+=1; c[i+1]-=1; if(i<n){ oper[num].x=i+1; oper[num++].y=i; }else{ oper[num].x=1; oper[num++].y=n; } } else if(abs(c[i])>1){ mark=1; break; } } if(mark){ continue; } if(c[1]+c[n+1]!=0){ continue; }else{ flag=1; break; } } if(flag){ printf("YES\n"); printf("%d\n",num); for(int i=0;i<num;i++){ printf("%d %d\n",oper[i].x,oper[i].y); } }else{ printf("NO\n"); } } } return 0; }
HDU 5353—— Average——————【贪心+枚举】
标签:
原文地址:http://www.cnblogs.com/chengsheng/p/4720135.html