HDU 5353 Average(枚举)

来源:互联网 发布:php 汉字转ascii 编辑:程序博客网 时间:2024/05/22 21:33

Average

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 678    Accepted Submission(s): 174
Special Judge


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.
 

Input
There are multiple test cases. The first line of input contains an integer T, indicating the number of test cases. For each test case:

The first contains an integer n (1n105), the number of soda.
The next line contains n integers a1,a2,,an (0ai109), where ai denotes the candy i-th soda has.
 

Output
For each test case, output "YES" (without the quotes) if possible, otherwise output "NO" (without the quotes) in the first line. If possible, then the output an integer m (0mn) in the second line denoting the number of operations needed. Then each of the following m lines contain two integers x and y (1x,yn), which means that x-th soda gives y-th soda a candy.
 

Sample Input
361 0 1 0 0 051 1 1 1 131 2 3
 

Sample Output
NOYES0YES22 13 2
 


题意:一个圆桌上有n个小盆友,每个小盆友都有一些糖果,问能不能通过相邻两个小盆友的传递糖果来实现每个小盆友都有同样多的糖果。(两个小盆友最多只能进行一次传递,并且每次传递只能传递一颗糖果。)
思路:先判断糖果总数能不能平均分给所有小盆友,如果能,那么传递方案最多就有两种,枚举每一种方案,哪种方案可行就采用哪种方案。细节在乱码中。。

#include <stdio.h>#include <stdlib.h>#include <iostream>#include <algorithm>#include <cstring>#include <math.h>#include <vector>#include <queue>#include <stack>using namespace std;struct P{    int a, b;};P rem[100010];int soda[100010];int a[200010], b[200010];int main(){    int t;    scanf("%d", &t);    while(t--)    {        int n;        scanf("%d", &n);        long long sum = 0;        for(int i = 1; i <= n; i ++)        {            scanf("%d", &soda[i]);            sum += soda[i];        }        bool flag = true;        int fir = 0, v;        if(sum % n != 0)        {            flag = false;        }        else        {            v = sum / n;            fir = 0;            for(int i = 1; i <= n; i++)            {                a[i] = soda[i] - v;                if(a[i] < -2 || a[i] > 2)                    flag = false;                if((a[i] == 1 || a[i] == 2) && ! fir) fir = i;                a[i + n] = a[i];                b[i] = b[i + n] = a[i];            }        }        int ans = 0;        if(flag && fir != 0)        {            bool action = true;            int no1 = fir, no2 = fir + 1;            a[no1]--, a[no2]++, a[no1 + n]--;            if(no1 > n)                no1 = no1 - n;            if(no2 > n)                no2 = no2 - n;            rem[ans].a = no1, rem[ans++].b = no2;            for(int i = fir + 1; i <= fir + n; i++)            {                if(a[i] == 2 || a[i] == -2)                {                    action = false;                    break;                }                else if(a[i] == 1)                {                    no1 = i, no2 = i + 1;                    a[no1]--, a[no2]++;                    if(no1 > n)                        no1 = no1 - n;                    if(no2 > n)                        no2 = no2 - n;                    rem[ans].a = no1, rem[ans++].b = no2;                }                else if(a[i] == -1)                {                    int nu = 0;                    for(int j = i + 1; j <= fir + n; j++)                    {                        if(a[j] == 1 || a[j] == 2)                        {                            nu = j;                            break;                        }                        else if(a[j] < 0)                        {                            action = false;                            break;                        }                    }                    for(int j = nu; j > i; j--)                    {                        no1 = j, no2 = j - 1;                        a[no1]--, a[no2]++;                        if(no1 > n)                            no1 = no1 - n;                        if(no2 > n)                            no2 = no2 - n;                        rem[ans].a = no1, rem[ans++].b = no2;                    }                }            }            if(!action)            {                ans = 0;                for(int i = fir + 1; i <= fir + n; i++)                {                    if(b[i] == 2 || b[i] == -2)                    {                        flag = false;                        break;                    }                    else if(b[i] == 1)                    {                        no1 = i, no2 = i + 1;                        b[no1]--, b[no2]++;                        if(no1 > n)                            no1 = no1 - n;                        if(no2 > n)                            no2 = no2 - n;                        rem[ans].a = no1, rem[ans++].b = no2;                    }                    else if(b[i] == -1)                    {                        int nu = 0;                        for(int j = i + 1; j <= fir + n; j++)                        {                            if(b[j] == 1 || b[j] == 2)                            {                                nu = j;                                break;                            }                            else if(b[j] < 0)                            {                                flag = false;                                break;                            }                        }                        for(int j = nu; j > i; j--)                        {                            no1 = j, no2 = j - 1;                            b[no1]--, b[no2]++;                            if(no1 > n)                                no1 = no1 - n;                            if(no2 > n)                                no2 = no2 - n;                            rem[ans].a = no1, rem[ans++].b = no2;                        }                    }                }            }        }        if(!flag)            printf("NO\n");        else        {            printf("YES\n%d\n", ans);            for(int i = 0; i < ans; i++)            {                printf("%d %d\n", rem[i].a, rem[i].b);            }        }    }    return 0;}


0 0
原创粉丝点击