HDU5353 Average


Problem Description
There are 
n soda sitting around a round table. soda are numbered from 
1 to 
n and 
i-th soda is adjacent to 
(i+1)-th soda, 
1-st soda is adjacent to 
n-th soda.
Each soda has some candies in their hand. And they want to make the number of candies the same by doing some taking and giving operations. More specifically, every two adjacent soda 
x and 
y can do one of the following operations only once:
1. 
x-th soda gives 
y-th soda a candy if he has one;
2. 
y-th soda gives 
x-th soda a candy if he has one;
3. they just do nothing.
Now you are to determine whether it is possible and give a sequence of operations.
N人は1周して、一人一人は左あるいは右に最大1つのキャンディをあげることができて、隣の2人は最大1回のキャンディの伝达(aはbに1つをあげて、bは更にaにあげることができません)
考え方:N人の中で一番多いのは必ず外にあげます(すべての人が同じように多くない限り)、もし彼が左に1つあげたら、左の人はもっと左の人とキャンディをあげるしかありません.操作をした後、最後の平均数と一致しなければ、この方法は間違っていて、もう1人目に右に1つあげて、それから同じ操作をします.これにより配列を時計回りと反時計回りに1回判別すればよい.
このような特例があるかもしれませんが、最初の順序で処理すると、ある人が左の人と操作していない可能性があります.その人のキャンディ数=平均値で、次の人も彼と操作することができないので、操作の方向は変わりません.
注意平均値を計算する際には、割り切れない場合を考慮します.
#include

using namespace std;


 const int SIZE = 100005;
 int a1[SIZE];
 int a2[SIZE];
 int N,ave;

 int ans[SIZE][2];
 int no = 0;

 int left(int p){
    p--;
    if(p < 0) p = N - 1;
    return p;
}

 int right(int p){
    p++;
    return p % N;
}

int main() {
    // TODO Auto-generated method stub
    int T;
    scanf("%d",&T);
    while(T--){
        scanf("%d",&N);
        long long sum = 0;
        int max = -1;
        int pos = 0;
        for(int i=0;i max){
                max = a1[i];
                pos = i;
            }
            sum += a1[i];
        }
        long long ln = N;
        if(sum%ln != 0){
            printf("NO
"); continue; } ave = (int)(sum / ln); if(a1[pos] - ave > 2 || a1[pos] - ave < -2){ printf("NO
"); continue; } bool flag = true; no = 0; int p = pos, next = left(p); for(int i=1;i<=N;i++){ if(a1[p] > ave){ a1[p]--; a1[next]++; ans[no][0] = p + 1; ans[no++][1] = next + 1; } else if(a1[p] < ave){ a1[p]++; a1[next]--; if(a1[next]<0){ flag = false; break; } ans[no][0] = next + 1; ans[no++][1] = p + 1; } if(i>1 && a1[p]!=ave){ flag = false; break; } p = next; next = left(next); } if(flag){ printf("YES
"); printf("%d
",no); if(no != 0){ for(int i=0;i ave){ a2[p]--; a2[next]++; ans[no][0] = p + 1; ans[no++][1] = next + 1; } else if(a2[p] < ave){ a2[p]++; a2[next]--; if(a2[next]<0){ flag = false; break; } ans[no][0] = next + 1; ans[no++][1] = p + 1; } if(i>1 && a2[p]!=ave){ flag = false; break; } p = next; next = right(next); } if(flag){ printf("YES
"); printf("%d
",no); if(no != 0){ for(int i=0;i