时间限制: 2 Sec 内存限制: 256 MB
题目描述
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
输入
The input is given from Standard Input in the following format:
N
A1 A2 … AN
输出
If it is possible to remove all the stones from the boxes, print YES. Otherwise, print NO.
样例输入
5
4 5 1 2 3
样例输出
YES
提示
All the stones can be removed in one operation by selecting the second box.
题目大概是说有n个盒子连成一个环,每次从某一个盒子里拿走1个石头,从后一个盒子里拿走2个石头,以此类推,到从选定的盒子的前一个拿走n个石头为止,问有没有方案能将所有石头恰好拿走。
我的思路是考虑比较第i个盒子与第(i+1)个盒子,只有两种可能,一种是从第i个盒子里拿走j个石头,并且从第(i+1)个盒子拿走(j+1)个石头(j!=n),另一种是从第i个盒子里拿走n个石头,并且从第(i+1)个盒子拿走1个石头。执行一次第一种操作,会使a(i+1)-ai==1;执行一次第二种操作,会使a(i+1)-ai==1-n。因为每执行一次操作,会减少(n+1)*n/2个石子,所以我们可以算出执行操作的次数,设其为m,设对第i个盒子执行了(m-k)次第一种操作,进行了k次第二种操作,那么a(i+1)-ai==(m-k)*1+k*(1-n),化简后得a(i+1)ai==m-nk,进一步求出k,k即为从第ai个盒子拿走一个石头的操作数,那么将所有的k加在一起,即为从某个盒子里拿走一个石头的操作数,即为总操作数。如果满足这些条件,则一定可以保证有恰好将所有石头拿走的方案,如果不满足,则一定没有。
#include <bits/stdc++.h>
int main()
{
long long a[100005]={0};
long long i,k,n,m,sum=0;
int flag=1;
scanf("%lld",&n);
for (i=0;i<n;i++)
{
scanf("%lld",a+i);
sum+=a[i];
}
if (sum%(n*(n+1)/2))
flag=0;
else
{
m=2*sum/n/(n+1);
if ((m-a[0]+a[n-1])%n) //是环所以对第一个和最后一个进行单独处理
flag=0;
else
{
k=(m-a[0]+a[n-1])/n;
for (i=1; i<n; i++)
{
if ((m-a[i]+a[i-1])%n||m<a[i]-a[i-1])
{
flag=0;
break;
}
k+=(m-a[i]+a[i-1])/n;
}
}
}
if (k!=m)
flag=0;
if (flag)
printf("YES\n");
else
printf("NO\n");
return 0;
}
|