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 个人围成一圈,每个人都有糖果。
每两个人之间只能经行三种操作,每种操作只能经行一次
- a给b一颗糖,如果a有糖
- b给a一颗糖,如果b有糖
- 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