1.题目描述:点击打开链接
2.解题思路:本题属于一个简单的模拟题,然而在比赛时候考虑不周WA了。本题要求相邻的两个人可以交换一个糖果,且仅能交换一次。首先计算所有糖果的个数sum,如果sum不能整除n,那么肯定无解。否则,计算出平均值mean,然后让a[i]-=mean得到差值。此时可以利用贪心法来解决本题。令第i个人只和第i+1个人之间进行糖果交换:
如果差值为-1,则第i+1个人给第i个人一个糖果;
如果差值为0,则无操作;
如果差值为1,则第i个人给第i+1个人一个糖果;
此时要注意第1个人与第n个人之间糖果交换的情况。一共有三种:不交换,第1个人给第n个人一个糖果,第n个人给第1个人一个糖果。
3.代码:
vector<P>ans;
int m;
bool solve(int n,int*a)//第0个人到第n-1个人的“顺序”操作
{
int ok=1;
for(int i=0;i<n;i++)
{
if(abs(a[i]>1))return false;
if(a[i]==-1)
{
ans.push_back(P(i+1,i));m++;
a[i]++;a[i+1]--;
}
if(a[i]==1)
{
ans.push_back(P(i,i+1));m++;
a[i]--;a[i+1]++;
}
}
return true;
}
const int N=100000+10;
int a[N];
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n;
ll sum=0;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
sum+=a[i];
}
if(sum%n)puts("NO");
else
{
int mean=sum/n;
for(int i=0;i<n;i++)
a[i]-=mean;
int b[N];
memcpy(b,a,sizeof(int)*n);
int ok=1;
m=0;ans.clear();
if(!solve(n,b))//第0个人和第n-1个人之间不交换
{
memcpy(b,a,sizeof(int)*n);
b[0]++;b[n-1]--;
m=1;ans.clear();ans.push_back(P(n-1,0));
if(!solve(n,a))//第0个人给第n-1个人一个糖果
{
memcpy(b,a,sizeof(int)*n);
b[0]--;b[n-1]++;
m=1;ans.clear();ans.push_back(P(0,n-1));
if(!solve(n,a))ok=0;//第n-1个人给第0个人一个糖果
}
}
if(ok)
{
puts("YES");
printf("%d\n",m);
for(int i=0;i<m;i++)
printf("%d %d\n",ans[i].first+1,ans[i].second+1);
}
}
}
}