AtCoder 2303 模拟

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 A2AN

Output

If it is possible to remove all the stones from the boxes, print YES. Otherwise, print NO.


Sample Input 1

Copy
5
4 5 1 2 3

Sample Output 1

Copy
YES

All the stones can be removed in one operation by selecting the second box.


Sample Input 2

Copy
5
6 9 12 10 8

Sample Output 2

Copy
YES

Sample Input 3

Copy
4
1 2 3 1

Sample Output 3

Copy
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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值