标签:多校
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