2015 Multi-University Training Contest 6 -- 1001 Average

来源:互联网 发布:全国行政区数据库 编辑:程序博客网 时间:2024/06/07 13:49

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个人围一圈,每个人都有ai的糖,相邻的人可以给一次糖,并且一次一颗,问是否能实现所有人的糖数量相等,并输出一种方案。

有两个容易想到的判断条件:
1、ai的和sum%n!=0,那么一定不行,输出“NO”;
2、相邻差的绝对值大于2,也不行,大于2之后一定无法使ai变成平均值;

接下来就是构造方案的问题,由于相邻的只能给一次糖,我们按一定的顺序构造,先将每个ai减去均值,由于前面2的判断条件,ai只能为-1,1,0,因此我们先确定a[1]的情况(a[1]给a[2]糖,a[2]给a[1]糖,什么都不做),然后依次考虑a[i]与a[i+1]的关系,a[i]=-1则a[i+1]给a[i]糖,a[i]=1则a[i]给a[i+1]糖,a[i]=0则什么都不用做>.<

开始WA了由于没考虑移动会出现负数的情况,比如5 1 1 1 1 1 可以不移动输出 YES 0 或者YES 5 2->1 3->2 4->3 5->4 1->5,但 5 0 0 0 0 0输出只能为YES 0,因为移动会产生负数,所以对于数字相同的加一个特判就可以了。

#include <bits/stdc++.h>using namespace std;long long a[100005], b[100005], c[100005], d[100005];int n;int cal(int x){    if(x == n - 1)return 0;    else return x + 1;}vector < pair <int,int> >p;int main(){    int T;    scanf("%d", &T);    while(T--)    {        scanf("%d", &n);p.clear();        long long sum = 0LL;        for(int i = 0; i < n; ++i)        {            scanf("%I64d", a + i);            b[i] = a[i];            c[i] = a[i];            sum += a[i];            d[i] = a[i];        }        if(sum % n != 0)        {            puts("NO");            continue;        }        long long x=a[0];bool ff=false;        for(int i=1;i<n;++i)        {            if(x!=a[i])ff=true;        }        sum /= n;        if(!ff)        {            puts("YES");            puts("0");            continue;        }        if(n == 2)        {            if(abs(a[0] - a[1]) > 2)puts("NO");            else if(abs(a[0] - a[1])==2)            {                puts("YES");                printf("%d\n", 1);                if(a[0]>a[1])puts("1 2");                else puts("2 1");            }            else            {                puts("YES");                puts("0");            }            continue;        }        ff=false;        for(int i = 0; i < n; ++i)        {            a[i] -= sum;            b[i] -= sum;            c[i] -= sum;            d[i] -= sum;            if(abs(a[i])>2){ff=true;break;}        }        if(ff)        {            puts("NO");            continue;        }        a[0]++;        a[1]--;        bool fa, fb, fc;        fa = fb = fc = true;        for(int i = 1; i < n; ++i)        {            if(a[i]==0)continue;            if(a[i] == 1)            {                a[cal(i)]++;                a[i] = 0;            }            else if(a[i] == -1)            {                a[cal(i)]--;                a[i] = 0;            }            else fa=false;        }        b[0]--;        b[1]++;        for(int i = 1; i < n; ++i)        {            if(b[i]==0)continue;            if(b[i] == 1)            {                b[cal(i)]++;                b[i] = 0;            }            else if(b[i] == -1)            {                b[cal(i)]--;                b[i] = 0;            }else fb=false;        }        for(int i = 1; i < n; ++i)        {            if(c[i]==0)continue;            if(c[i] == 1)            {                c[cal(i)]++;                c[i] = 0;            }            else if(c[i] == -1)            {                c[cal(i)]--;                c[i] = 0;            }else fc=false;        }        for(int i = 0; i < n; ++i)        {            if(a[i] != 0)fa = false;            if(b[i] != 0)fb = false;            if(c[i] != 0)fc = false;        }        if(!fa && !fb && !fc)        {            puts("NO");            continue;        }        puts("YES");        if(fa)        {            d[0]++;            d[1]--;            p.push_back(make_pair(2,1));            for(int i = 1; i < n; ++i)            {                if(d[i] == 1)                {                    d[cal(i)]++;                    d[i] = 0;                    p.push_back(make_pair(i+1,cal(i)+1));                }                else if(d[i] == -1)                {                    d[cal(i)]--;                    d[i] = 0;                    p.push_back(make_pair(cal(i)+1,i+1));                }            }            int len=p.size();            printf("%d\n",len);            for(int i=0;i<len;++i)            {                printf("%d %d\n",p[i].first,p[i].second);            }            continue;        }        if(fb)        {            d[0]--;            d[1]++;            p.push_back(make_pair(1,2));            for(int i = 1; i < n; ++i)            {                if(d[i] == 1)                {                    d[cal(i)]++;                    d[i] = 0;                    p.push_back(make_pair(i+1,cal(i)+1));                }                else if(d[i] == -1)                {                    d[cal(i)]--;                    d[i] = 0;                    p.push_back(make_pair(cal(i)+1,i+1));                }            }            int len=p.size();            printf("%d\n",len);            for(int i=0;i<len;++i)            {                printf("%d %d\n",p[i].first,p[i].second);            }            continue;        }        if(fc)        {            for(int i = 1; i < n; ++i)            {                if(d[i] == 1)                {                    d[cal(i)]++;                    d[i] = 0;                    p.push_back(make_pair(i+1,cal(i)+1));                }                else if(d[i] == -1)                {                    d[cal(i)]--;                    d[i] = 0;                    p.push_back(make_pair(cal(i)+1,i+1));                }            }            int len=p.size();            printf("%d\n",len);            for(int i=0;i<len;++i)            {                printf("%d %d\n",p[i].first,p[i].second);            }            continue;        }    }    return 0;}
0 0
原创粉丝点击