构造——AtCoder Grand Contest 010 B

    xiaoxiao2021-03-26  26

    题目链接:http://agc010.contest.atcoder.jp/tasks/agc010_b

    题意:给出N个盒子围成一个圈,并标记好1—N,每个盒子含有一定数量的石子,每次选中一个盒子 Ai ,然后从第 Ai+j 个盒子中拿走 j 个石子,j从1到N遍历,不断进行这样的操作直到所有的盒子都为空或者在每一次操作中,第 Ai+j 个盒子中少于 j 个石子。如果最后所有的盒子都能拿空则返回YES,否则返回NO.

    分析:即判断这组数能否由整数个(即x y个)1,2,...,N构成,我们判断前后两个盒子之间的差值是有 x 1 y (N1)的和构成的,所以遍历数组,看每一个差值是否满足这个条件。

    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"); }
    转载请注明原文地址: https://ju.6miu.com/read-662486.html

    最新回复(0)