zoukankan      html  css  js  c++  java
  • POJ 2356 Find a multiple (抽屉原理)

      感觉这个题很不错,至少开始真的没想道可以用抽屉原理推出一个结论,然后把这题秒掉。。。。

    已知有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;
    }
  • 相关阅读:
    PNG文件格式具体解释
    opencv2对读书笔记——使用均值漂移算法查找物体
    Jackson的Json转换
    Java实现 蓝桥杯VIP 算法训练 装箱问题
    Java实现 蓝桥杯VIP 算法训练 装箱问题
    Java实现 蓝桥杯VIP 算法训练 单词接龙
    Java实现 蓝桥杯VIP 算法训练 单词接龙
    Java实现 蓝桥杯VIP 算法训练 方格取数
    Java实现 蓝桥杯VIP 算法训练 方格取数
    Java实现 蓝桥杯VIP 算法训练 单词接龙
  • 原文地址:https://www.cnblogs.com/vongang/p/2752317.html
Copyright © 2011-2022 走看看