题意:给定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;
}