标签:多校
3 6 1 0 1 0 0 0 5 1 1 1 1 1 3 1 2 3
NO YES 0 YES 2 2 1 3 2
#include<stdio.h>
#include<string.h>
#define ll __int64
const int N = 100005;
struct EDG{
int x,y;
};
int n,step;
ll a[N],b[N],avg;
EDG edg[N<<1];
void addEdg(int x,int y)
{
edg[step].x=x;
edg[step].y=y;
step++;
}
bool findout(int l)
{
while(l<=n){
if(a[l]==avg){l++;continue;}
if(l==n)return 0;
if(a[l]>avg){
if(a[l]-avg>1){
return 0;
}
else{
l++;
a[l]++;
a[l-1]--;
addEdg(l-1 , l); //从左向右过一个
}
}
else {
if(avg-a[l]>1){
return 0;
}
if(a[l+1]<avg){
return 0;
}
l++; a[l]--; a[l-1]++;
addEdg(l , l-1); //从右向左过一个
}
}
return 1;
}
void print()
{
printf("YES\n%d\n",step);
for(int i=0; i<step; i++)
printf("%d %d\n",edg[i].x,edg[i].y);
}
int main()
{
int T;
scanf("%d",&T);
while(T--){
scanf("%d",&n);
avg=0;
for(int i=1; i<=n; i++)
{
scanf("%I64d",&b[i]);
avg+=b[i] ;
}
if(avg%n!=0){
printf("NO\n");continue;
}
avg/=n;
step=0;
//因是一个圈,所以从第1 个分情况讨论,注意每次求完一轮把step 初始为0,我就是在这个WA了好多次
if(b[1]-avg==2){
for(int i=1; i<=n; i++)
a[i]=b[i];
a[1]--; a[2]++; addEdg(1 , 2);
if(n>2){
a[1]--;a[n]++; addEdg(1, n);
if( findout(1) ){
print(); continue;
}
}
}
else if(b[1]-avg==-2){
if(b[2]&&b[n]){
for(int i=1; i<=n; i++)
a[i]=b[i];
a[1]++; a[2]--; addEdg(2 , 1);
if(n>2){
a[1]++;a[n]--; addEdg(n, 1);
if( findout(1) ){
print(); continue;
}
}
}
}
else if(b[1]-avg==1){
for(int i=1; i<=n; i++)
a[i]=b[i];
a[1]--; a[2]++; addEdg(1 , 2);
if( findout(1) ){
print(); continue;
}
step=0;
for(int i=1; i<=n; i++)
a[i]=b[i];
a[1]--; a[n]++; addEdg(1 , n);
if( findout(1) ){
print(); continue;
}
}
else if(b[1]-avg==-1){
if(b[2]){
for(int i=1; i<=n; i++)
a[i]=b[i];
a[1]++; a[2]--; addEdg(2 , 1);
if( findout(1) ){
print(); continue;
}
}
step=0;
if(b[n]){
for(int i=1; i<=n; i++)
a[i]=b[i];
a[1]++; a[n]--; addEdg(n , 1);
if( findout(1) ){
print(); continue;
}
}
}
else if(avg==b[1]){
for(int i=1; i<=n; i++)
a[i]=b[i];
if( findout(1) ){
print(); continue;
}
step=0;
if(b[2]){
for(int i=1; i<=n; i++)
a[i]=b[i];
a[n]++; a[2]--; addEdg(1 , n); addEdg(2 , 1);
if( findout(1) ){
print(); continue;
}
}
step=0;
if(b[n]){
for(int i=1; i<=n; i++)
a[i]=b[i];
a[n]--; a[2]++;addEdg(1 , 2); addEdg(n , 1);
if( findout(1) ){
print(); continue;
}
}
}
printf("NO\n");
}
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:多校
原文地址:http://blog.csdn.net/u010372095/article/details/47394977