感觉这个题很不错,至少开始真的没想道可以用抽屉原理推出一个结论,然后把这题秒掉。。。。
已知有n个元素,sum[i]表示从1到i所有数的和。。。sum[i]%n可以得到一个剩余系,如果出现0,那么结果就找到了。
如果不出现0,就可以用抽屉原理了。因为剩余系里只有[1,n-1]这些数,但是sum[i]%n会得到n个结果。
n-1个抽屉放n个物品,必定有一个抽屉放的物品数大于等于2。
也就是必定存在sum[j]%n == sum[i]%n。我们假设sum[i] > sum[j],所以有(sum[i] - sum[j])%n = 0; 从而得到结果。
构造大概有O(n)的复杂度吧,开始想写O(n^2)。感觉不靠谱,也没敢写。
//#pragma comment(linker,"/STACK:327680000,327680000") #include <iostream> #include <cstdio> #include <cmath> #include <vector> #include <cstring> #include <algorithm> #include <string> #include <set> #include <functional> #include <numeric> #include <sstream> #include <stack> #include <map> #include <queue> #define CL(arr, val) memset(arr, val, sizeof(arr)) #define REP(i, n) for((i) = 0; (i) < (n); ++(i)) #define FOR(i, l, h) for((i) = (l); (i) <= (h); ++(i)) #define FORD(i, h, l) for((i) = (h); (i) >= (l); --(i)) #define L(x) (x) << 1 #define R(x) (x) << 1 | 1 #define MID(l, r) (l + r) >> 1 #define Min(x, y) (x) < (y) ? (x) : (y) #define Max(x, y) (x) < (y) ? (y) : (x) #define E(x) (1 << (x)) #define iabs(x) (x) < 0 ? -(x) : (x) #define OUT(x) printf("%I64d\n", x) #define Read() freopen("data.in", "r", stdin) #define Write() freopen("data.out", "w", stdout); typedef long long LL; const double eps = 1e-8; const double pi = acos(-1.0); const double inf = ~0u>>2; using namespace std; const int N = 10010; int sum[N]; int a[N]; vector<int> v[N]; int main() { //Read(); int n, i, j; scanf("%d", &n); for(i = 1; i <= n; ++i) { scanf("%d", a + i); v[i].clear(); } sum[0] = 0; for(i = 1; i <= n; ++i) { sum[i] = a[i] + sum[i-1]; v[sum[i]%n].push_back(i); if(sum[i]%n == 0) { printf("%d\n", i); for(j = 1; j <= i; ++j) { printf("%d\n", a[j]); } return 0; } } for(i = 1; i <= n; ++i) { if(v[i].size() >= 2) { int l = v[i][0], r = v[i][1]; printf("%d\n", r - l); for(j = l + 1; j <= r; ++j) { printf("%d\n", a[j]); } return 0; } } return 0; }