zoukankan      html  css  js  c++  java
  • UPC-5627 Boxes(思维)

    题目描述
    There are N boxes arranged in a circle. The i-th box contains Ai stones.

    Determine whether it is possible to remove all the stones from the boxes by repeatedly performing the following operation:

    Select one box. Let the box be the i-th box. Then, for each j from 1 through N, remove exactly j stones from the (i+j)-th box. Here, the (N+k)-th box is identified with the k-th box.
    Note that the operation cannot be performed if there is a box that does not contain enough number of stones to be removed.

    Constraints
    1≤N≤105
    1≤Ai≤109
    输入
    The input is given from Standard Input in the following format:

    N
    A1 A2 … AN
    输出
    If it is possible to remove all the stones from the boxes, print YES. Otherwise, print NO.
    样例输入
    5
    4 5 1 2 3
    样例输出
    YES
    提示
    All the stones can be removed in one operation by selecting the second box.

    题意:输入一个序列,这个序列成环形,头尾相接,每次选择序列中一个数作为起点,以顺时针方向依次对每个值做减i操作,i从1到n,保证最后整个序列每个值都被减到0,而不会出现负数的情况。问是否能这样依次减到0,若给出的 序列可以,则输出YES,否则输出NO

    我们可以反过来想,对于一个序列,我们选择一个数作为起点依次加i,最后达到给出序列的值的状态。首先,我们要求出层数,也就是我对这个环做了多少轮从1加到N的操作。因为每次都是最序列的值做1加到N的操作,所以我们每轮操作加上的值即等差数列求和公式n*(n+1)/2. 如果数列可以在整数轮次被削减完,那么可能有解,否则一定无解,那么我们对数列求和,除n * (n+1)/2,即做的操作次数,若取模不为零,则一定输出NO。

    接下来对于每个数考虑,我们对于一轮增加,两两数之间定有一个断电,如,五个数,对于其中两个相邻的数,必定是,一个加了1,另一个加了5,而这两个相邻的数认为是一个断点。因为两两连续的数之间增值后,必定差值为1,如1和2差值为1,3和4差值为1,而1和5差值为4,这个断点使得某两数差值为n-1,我们计算两两相邻数的差值,若发现小于轮数,那么这两个数之间必有断点,因为断点使差值减了(n-1)否则,差值为1,有t层则差值为t。

    对于两数,我们进行多轮操作后,可能有断点,可能是一层一层叠上来的。断点和普通层叠的次数之和为总轮数,那么射、设断点次数为x,普通层叠为y,则x+y=t(总轮数)

    再者,我们计算得到的相邻两数差值tmp,tmp=-x*(n-1)+y

    这是对于差值的解释,无断点差值+1,有断点差值-n+1

    化简后,x=(t-tmp)/n

    即计算x断点次数,我们对于每个差值,计算出在此存在的断点次数,求和所有两数之间的断点次数,若正确的话,断点次数和等于轮数,否则断点次数不合理,多了或者少了。

    注意要考虑的情况,1 2 3 4 5有解,5 4 3 2 1无解
    1 1 1 1 1无解
    15 15 15 15 15有解
    2 3 4 5 6无解,因为多次轮数是正确的,但基础1 1 1 1 1是有误的,在有误的基础上正确增长也是错误的。

    对于两数之差,若大于总层数,必定无解。若求断点数不是整数,必定无解,此处用来解决2 3 4 5 6的情况。

    #include<bits/stdc++.h>
    #define LL long long
    using namespace std;
    const int maxn=100005;
    int main()
    {
        LL n,a[maxn],b[maxn];
        while(scanf("%lld",&n)!=EOF)
        {
            LL sum=0;
            for(int i=0; i<n; i++)
            {
                scanf("%lld",&a[i]);
                sum+=a[i];
            }
            bool ans=true;
            LL t=sum/(n*(n+1)/2);
            LL tt=t;
            for(int i=0; i<n; i++)
            {
                LL tmp=a[i]-a[(i-1+n)%n];
                if((t-tmp)%n!=0||t<tmp) ans=false;
                else tt-=(t-tmp)/n;
            }
    //        printf("%lld    %lld    %lld
    ",sum%(n*(n+1)/2),sum,n*(n+1)/2);
            printf("%s
    ",ans&&sum%(n*(n+1)/2)==0&&tt==0?"YES":"NO");
        }
    }
    
  • 相关阅读:
    [Form Builder]POST 与 commit_form 的区别
    [Form Builder]Form中的validate验证事件
    [Form Builder]Oracle Form系统变量中文版总结大全
    [Form Builder]NAME_IN()与COPY()
    [Form Builder]APP_ITEM_PROPERTY.SET_PROPERTY 用法
    解决MVC模式文件下载附件中文名称乱码
    [ASP.NET MVC]笔记(四) UnobtruSive AJAX和客户端验证
    log4net的使用
    Linq 实现sql中的not in和in条件查询
    [ASP.NET MVC]笔记(三) 成员资格、授权和安全性
  • 原文地址:https://www.cnblogs.com/kuronekonano/p/11135790.html
Copyright © 2011-2022 走看看