【题意】一堆小朋友围成一个圈,第i和小朋友有ai颗糖果,每个小朋友最多给他左右两边的一次且一颗糖果,可以不给,求最后能否使所有小朋友的糖果数量一样。
【分析】首先所有糖果总数要能除尽n,否则必然不能平分,然后求出平均数,让所有糖果减去平均数,最后目标使得所有ai为0,只要第一个小朋友的操作确定,就能递推出所有小朋友的糖果数量,如果当前a[i] = 1,则必须要给一颗糖果给i+1,如果a[i]=-1,则说明此时先借用了右边的某个糖果,所以需要把i+1的一颗给i;则操作完如果某个a[i]的绝对值超过1(2也不行,因为不能给右边的两个,而左边的已经为0,也不能给)就返回不可能;需要注意n为1的时候以及所有糖果总数为0不能给糖果,直接YES。又无耻的用了输入输出挂。
【AC CODE】109ms
#include <bits/stdc++.h> using namespace std; typedef long long LL; typedef pair<int,int> P; #define rep(i,a,n) for(int i = a; i < n; i++) #define repe(i,a,n) for(int i = a; i <= n; i++) #define per(i,n,a) for(int i = n; i >= a; i--) #define clc(a,b) memset(a,b,sizeof(a)) const int INF = 0x3f3f3f3f, MAXBUF = 10000, MAXOUT = 10000, MAXN = 100000+10; char buf[MAXBUF], *ps = buf, *pe = buf+1; inline void rnext(){ if(++ps == pe) pe = (ps = buf)+fread(buf,sizeof(char),sizeof(buf)/sizeof(char),stdin); } template <class T> inline bool in(T &ans) { ans = 0; T f = 1; if(ps == pe) return false;//EOF do{ rnext(); if('-' == *ps) f = -1; }while(!isdigit(*ps) && ps != pe); if(ps == pe) return false;//EOF do { ans = (ans<<1)+(ans<<3)+*ps-48; rnext(); }while(isdigit(*ps) && ps != pe); ans *= f; return true; } char bufout[MAXOUT], outtmp[50],*pout = bufout, *pend = bufout+MAXOUT; inline void write() { fwrite(bufout,sizeof(char),pout-bufout,stdout); pout = bufout; } inline void out_char(char c){ *(pout++) = c;if(pout == pend) write();} inline void out_str(char *s) { while(*s) { *(pout++) = *(s++); if(pout == pend) write(); } } template <class T> inline void out_int(T x) { if(!x) { out_char('0'); return; } if(x < 0) x = -x,out_char('-'); int len = 0; while(x) { outtmp[len++] = x%10+48; x /= 10; } outtmp[len] = 0; for(int i = 0, j = len-1; i < j; i++,j--) swap(outtmp[i],outtmp[j]); out_str(outtmp); } int a[MAXN],b[MAXN],n,tol; LL sum; P ans[MAXN]; bool ok(int v) { tol = 0; memcpy(b,a,sizeof(int)*n); b[0] -= v; b[1] += v; if(-1 == v) ans[tol++] = {1,0}; else if(1 == v) ans[tol++] = {0,1}; rep(i,1,n) { int nxt = (i+1)%n; if(b[i] == 1) { b[nxt]++; ans[tol++] = {i,nxt}; } else if(b[i] == -1) { b[nxt]--; ans[tol++] = {nxt,i}; } if(abs(b[nxt]) > 1) return false; } return true; } bool all_zero() { rep(i,0,n) if(a[i]) return false; return true; } bool sloved() { if(1 == n) { tol = 0; return true; } if(sum%n) return false; int avg = sum/n; rep(i,0,n) a[i] -= avg; if(all_zero()) { tol = 0; return true; } if(ok(-1) || ok(0) || ok(1)) return true; return false; } int main() { #ifdef SHY freopen("d:\\1.txt", "r", stdin); #endif int t; in(t); while(t--) { sum = 0; in(n); rep(i,0,n) in(a[i]), sum += a[i]; if(!sloved()) out_str("NO\n"); else { out_str("YES\n"); out_int(tol),out_char('\n'); rep(i,0,tol) out_int(ans[i].first+1),out_char(' '),out_int(ans[i].second+1),out_char('\n'); } } write(); return 0; }