Boxes
Time limit : 2sec / Memory limit : 256MB
Score : 500 points
Problem Statement
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
Input
The input is given from Standard Input in the following format:
N A1 A2 … AN
Output
If it is possible to remove all the stones from the boxes, print YES
. Otherwise, print NO
.
Sample Input 1
5 4 5 1 2 3
Sample Output 1
YES
All the stones can be removed in one operation by selecting the second box.
Sample Input 2
5 6 9 12 10 8
Sample Output 2
YES
Sample Input 3
4 1 2 3 1
Sample Output 3
NO
给出N个盒子,每个盒子装有Ai个石头。
每次操作可以选择一个盒子i,对于每个j(1 <= j <= N),从第(i+j)个盒子移走j个石头(第N+k个盒子即为第k个盒子)
如果存在一个盒子的石头数目不够操作将不能进行。求能否将所有的石头移走。
题解:反过来考虑 相当于每次放1-n n个数
每次操作两个相邻的盒子的差是1或1-n
那么所有的数和记为sum sum一定能整除n*(n+1)/2 否则就是no
然后sum/n/(n+1)/2就是轮数
记dis[i]为a[i]-a[i-1]
所以x+y=sum x+y(1-n)=dis[i]
sum-dis[i]=ny
y=(sum-dis[i])/n
y就为以这个点为起点的轮数 叠加起来检验是否等于sum(轮数)即可
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
ll a[100005],dis[100005];
int main(){
ll n,i;
scanf("%lld",&n);
ll sum=0;
for(i=1;i<=n;i++)scanf("%lld",&a[i]),sum+=a[i];
if(sum%(n*(n+1)/2)){
printf("NO\n");
return 0;
}
sum/=(n*(n+1))/2;
dis[1]=a[1]-a[n];
for(i=2;i<=n;i++)dis[i]=a[i]-a[i-1];
ll cnt=0;
for(i=1;i<=n;i++){
if((sum-dis[i]<0)||(sum-dis[i])%n){
printf("NO\n");
return 0;
}
else cnt+=(sum-dis[i])/n;
}
if(cnt!=sum)printf("NO\n");
else printf("YES\n");
return 0;
}