题意:给出N个盒子围成一个圈,并标记好1—N,每个盒子含有一定数量的石子,每次选中一个盒子 Ai ,然后从第 Ai+j 个盒子中拿走 j 个石子,
j 从1到N遍历,不断进行这样的操作直到所有的盒子都为空或者在每一次操作中,第 Ai+j 个盒子中少于 j 个石子。如果最后所有的盒子都能拿空则返回YES,否则返回NO.分析:即判断这组数能否由整数个(即x+y个)
1,2,...,N 构成,我们判断前后两个盒子之间的差值是有 x 个+1 和 y 个−(N−1) 的和构成的,所以遍历数组,看每一个差值是否满足这个条件。P.S. :因为过程中N*(N+1)会爆int范围,所以N的值最好开始设置成long long !!!(/(ㄒoㄒ)/~~)
AC代码
/*************************************************************************
> File Name: test.cpp
> Author: Akira
> Mail: qaq.febr2.qaq@gmail.com
************************************************************************/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <cmath>
#include <vector>
#include <set>
#include <list>
#include <ctime>
typedef long long LL;
typedef unsigned long long ULL;
typedef long double LD;
#define MST(a,b) memset(a,b,sizeof(a))
#define CLR(a) MST(a,0)
#define Sqr(a) ((a)*(a))
using namespace std;
#define MaxN 100001
#define MaxM MaxN*10
#define INF 0x3f3f3f3f
#define bug cout<<88888888<<endl;
#define MIN(x,y) (x<y?x:y)
#define MAX(x,y) (x>y?x:y)
LL N;
LL A[MaxN];
int main()
{
LL sum = 0;
scanf("%lld", &N);
for(int i=0;i<N;i++)
{
scanf("%lld", &A[i]);
sum+=A[i];
}
LL tmp = (1+N)*N/2;
if(sum%tmp) printf("NO\n");
else
{
int flag = 0;
LL num = sum/tmp;
LL x=0;
LL y=0;
for(int i=0;i<N;i++)
{
LL d;
if(i==0) d = A[0]-A[N-1];
else d = A[i] - A[i-1];
d = d + num*(N-1);
if( d % N !=0 )
{
flag = 1;
break;
}
else
{
d = d/N;
if(d<0 || d>num)
{
flag = 1;
break;
}
else
{
x+=d;
y+=(num-d);
}
}
}
if(flag) printf("NO\n");
else
{
//cout << x << " " << y << endl;
if( (x - y*(N-1)) == 0) printf("YES\n");
else printf("NO\n");
}
}
// system("pause");
}