A. 小盒子
题意+思路:
题意其实概括的不是非常准确 简要题意: 圆盒有n个格子, 格子自带ai个棋子.是否通过任意起点通过顺时针-1, -2, ... , -n的操作使得 圆盒中所有所有的棋子都为0 思路: 贪心 对于所有棋子通过顺时针操作的时候每一次都是(1 + n) * n / 2次 是一个等差公式所以提前判断所有的值累加起来是否能被除尽,如果不能被 除尽则代表着棋子不能清零.如果可以除尽,总次数是sum / ((1 + n) * n / 2) 次 记录为cnt,那么通过差分得到diff数组,不难得出差分数组是1个di加上n - 1其余 都是减去-1, 那么要让di = 0则需要操作为[(n - 1) * x - (cnt - x) + di == 0] 得到x = (cnt - di) / n及x操作是正整数及cnt - di它是n的倍数, cnt - di也需要>0 那么可以得到一个公式如果当前di - cnt <= 0且保证 (di - cnt) % n == 0 如果所有的di都满足这个条件那么可以清空棋子,否则不可以清空
Code:
#include <bits/stdc++.h> using namespace std; typedef long long ll; typedef unsigned long long ull; #define all(x) (x).begin(), (x).end() #define debug(x) cout << #x << ' ' << '=' << ' ' << (x) << '\n' #define debug2(x, y) cout << #x << ' ' << '=' << ' ' << (x) << ',' << ' ' << #y << ' ' << '=' << ' ' << (y) << ' ' << '\n' mt19937 rng(std::chrono::system_clock::now().time_since_epoch().count()); const int N = 1e5 + 5; ll a[N], diff[N]; void solve() { ll n; ll sum = 0; cin >> n; for (int i = 0; i < n; i++) { cin >> a[i]; sum += a[i]; } if (sum % ((1 + n) * n / 2)) { cout << "NO"; exit(0); } ll cnt = sum / ((1 + n) * n / 2); for (int i = 0; i < n; i++) { diff[i] = a[(i + 1) % n] - a[i] - cnt; } for (int i = 0; i < n; i++) { if (diff[i] > 0 || diff[i] % n) { cout << "NO\n"; return ; } } cout << "YES\n"; return ; } int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); cout << fixed << setprecision(15); int _ = 1; // cin >> _; while (_--) { solve(); } return 0; }