AtCoder Grand Contest 010 B - Boxes 验证解的存在性 2017/2/6

来源:互联网 发布:python黑客教程 编辑:程序博客网 时间:2024/05/29 09:57

题意:给定N个围成一圈的数,重复进行下述操作: 挑选第i个数,从i+1转一圈回到i,依次减去1到N。 问是否存在一种操作使得最后整圈的数全为0。

解题方法: 逆向思维好题! 将该过程倒着来看,就是每轮选择第i个数,从i+1转一圈回到i,依次加上1到N,将该操作设为操作1。问最后能否加到给定数列。令d[i]=a[i]-a[i-1],即考虑前数与后数之间的差,会发现,每次进行操作1时,差分的改变要么+1,要么-N+1,且两种情况里都有+1。故将差分减去s(操作的轮数),即处理掉+1的影响后。-N出现的次数恰为操作的轮数。

#include <bits/stdc++.h>using namespace std;typedef long long LL;const int maxn = 100010;LL a[maxn];LL sum;int main(){    LL n;    scanf("%lld", &n);    for(int i = 1; i <= n; i++){        scanf("%lld", &a[i]);        sum += a[i];        a[i-1] = a[i] - a[i-1];    }    a[0] = a[0] - a[n];    if(n == 1){        printf("YES\n");        return 0;    }    if((sum*2)%(n*(n+1))){        printf("NO\n");        return 0;    }    LL ans = 0;    LL cnt = sum / (n*(n+1)/2);    for(int i = 0; i < n; i++){        a[i] -= cnt;        if(a[i] % n || a[i] > 0){            printf("NO\n");            return 0;        }        ans += a[i] / (-n);    }    if(cnt == ans){        printf("YES\n");    }    else{        printf("NO\n");    }    return 0;}
0 0
原创粉丝点击