问题 K: Boxes
时间限制: 2 Sec 内存限制: 256 MB提交: 333 解决: 80
[ 提交][ 状态][ 讨论版][命题人: admin]
题目描述
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
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
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个盒子,每个盒子有a【i】个石头,可以进行多组操作,每次选中一个盒子然后依次在离选中盒子的i-th拿出i个石头(围成一个圈顺时针操作),问是否在若干组后能否正好拿完。
反思:
1.看到数据n 1e9 理所当然的以为用int 就可以,结果没想到后来求n*(n+1)/2 爆掉了。
2.看清题意 是顺时针,注意差分的方向。
细想,他们之和一定是1+2+.....n的倍数,只有满足此条件才能若干操作恰好拿完,先求出要进行几次操作t=sum/((n*n+1)/2)。每次操作除了第一个数和最后一个数减去的数相差(1-n),其他相邻的都是相差1,所以由此想到差分,因为每次都是后面的比前面的多减1而已,那么求出a【i】-a【i-1】 就是相差的这个数。如果不考虑第一个跟最后一个数,那么其他的一定为t,因为t次后他们没有了差值都为0,但是不为t的话一定就是(1-n)的改变了他们的差值,所以t-(a【i】-a【i-1】)一定要为n的倍数,而且这个数就是选定这个数几次进行操作。然后判断他们之和是否为t。
代码实现:
#include<bits/stdc++.h> using namespace std; #define ll long long const int maxn=1e5+7; int a[maxn]; int dis[maxn]; int main() { ll n; cin>>n; ll sum=0; for(int i=1;i<=n;i++) { cin>>a[i]; sum+=a[i]; } for(int i=2;i<=n;i++) { dis[i]=a[i]-a[i-1]; } dis[1]=a[1]-a[n]; if(sum%(n*(n+1)/2)) { cout<<"NO"<<endl; return 0; } ll t=sum/(n*(n+1)/2); int cnt=0; for(int i=1;i<=n;i++) { if(((t-dis[i])%n)||((t-dis[i])<0)) { cout<<"NO"<<endl; return 0; } cnt+=((t-dis[i])/n); } if(cnt!=t) cout<<"NO"<<endl; else cout<<"YES"<<endl; return 0; }