Average
题解:首先如果总糖果数不能整除 n n n就输出 N O NO NO。其次考虑两个方向变为暂时只朝一个方向,每个人与平均值的差,如果比平均值少一就从后一个人那里拿一个,如果比平均值多一个就给后一个人一个,如果等于平均值就什么也不做。因此枚举左右方向两次,最后每次枚举模拟完判断一下是否最后平分了就可以了。
#include<bits/stdc++.h>
typedef long long LL;
#define P pair<int,int>
using namespace std;
int a[100100], b[100100], n;
vector< P > ans;
bool solve(int start,int d)
{
ans.clear();
memcpy(b,a,sizeof a);
int f = 0;
if(b[start] == 2) {
int s = start, e = (s - d + n) % n;
b[s]--, b[e]++;
ans.push_back(P(s+1,e+1));
f = 1;
}
for(int i = 0; i < n - f; ++i) {
int s = (start + i * d + n) % n, e = (start + (1 + i) * d + n) % n;
int diff = b[s];
if(diff == 1) {
ans.push_back(make_pair(s + 1, e + 1));
b[s]--; b[e]++;
}else if(diff == -1) {
ans.push_back(make_pair(e + 1, s + 1));
b[s]++; b[e]--;
}else if(diff == 0){
continue;
}else{
return 0;
}
}
for(int i = 0; i < n; ++i) if(b[i]) return 0;
printf("YES\n%d\n", (int)ans.size());
for(int i = 0; i < ans.size(); ++i) {
printf("%d %d\n",ans[i].first, ans[i].second);
}
return 1;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("input.in","r",stdin);
#endif
int T;
cin>>T;
while(T--) {
scanf("%d",&n);
LL sum = 0;
int max1 = 0, id = 0;
for(int i = 0; i < n; ++i) {
scanf("%d",a+i);
sum += a[i];
}
if(sum % n != 0) {
puts("NO");
continue;
}
int av = sum / n, f = 1;
for(int i = 0; i < n; ++i) a[i] -= av;
for(int i = 0; i < n; ++i) {
if(abs(a[i]) > 2 || (n == 2 && abs(a[0]) >= 2)) {
puts("NO");
f = 0;
break;
}
}
if(!f) continue;
for(int i = 0; i < n; ++i) {
if(a[i] > 0) { id = i; break; }
}
int ok = 1;
if(!solve(id,1)) ok = solve(id,-1);
if(ok == 0) puts("NO");
}
return 0;
}