zoukankan      html  css  js  c++  java
  • 奶牛卧室

    题目链接:http://acm.swust.edu.cn/oj/problem/91/

    这道题让我想起了hash,题意可以描述为为 n 个数(a[1…n])寻找一个最小的数 K,使得这 n 个数对 K 取模无冲突。

    (nleq5000, a[i]in[1, 1000000])

    看了一个题解,A是A了,但是复杂度不是很好理解。并且这道题貌似有BUG,只对差作标记而不考虑差的约数的代码也通过了,显然可以构造出对应的样例:

    输入:2 1 5

    输出:3

    目前对这个题解理解的并不是很清晰,还没有找到这道题的出处和更好的解法。

    如果不考虑复杂度,暴力的方法将会是对每个差的大于n的约数标记,然后从n开始递增找第一个未被标记的数。

    差的范围也是[1, 1000000],如果暴力遍历每个数的约数,那必定超时。

    反过来考虑,遍历每个可能的约数:因为满足条件的约数在([n, max{{|a[i]-a[j]|}}])之间,这样所有可能的约数在1000000级别,如果考虑每个约数都对应着一个另一个因子,这个因子可以进行素因子分解,素因子的范围不超过(sqrt{1000000}=1000),1000以内的素数不超过200个,这样加上一些细节优化,就有可能通过时限(5s)了。

    这里标记约数的方法很巧妙,见代码。

    // http://acm.swust.edu.cn/oj/problem/91/
    # include <stdio.h>
    # include <stdlib.h>
    
    # define INDEX(i) ((i)>>3)
    # define OFF(i) ((i)&0x7)
    
    # define GET(i) (ok[INDEX(i)]>>OFF(i) & 0x1)
    # define SET(i) (ok[INDEX(i)] |= 0x1<<OFF(i))
    
    int pt[200], pn = 0;
    
    bool isPrime(int x) {
        if (x%2==0) return x==2;
        if (x%3==0) return x==3;
        if (x%5==0) return x==5;
        for (int i = 7; i*i <= x; i+=2) {
            if (x%i==0) return 0;
        }
        return 1;
    }
    
    int n;
    int s[5005];
    char ok[INDEX(1000001)+1];
    
    int main()
    {
        for (int i = 2; i < 1001; i+=2) {
            if (isPrime(i)) pt[pn++] = i;
        }
        
        scanf("%d", &n);
        for (int i = 0; i < n; ++i) scanf("%d", &s[i]);
        
        int mx = 0;
        for (int i = 0; i < n; ++i) {
            for (int j = i+1; j < n; ++j) {
                int t = (int)abs(s[i]-s[j]);
                SET(t);
                if (t > mx) mx = t;
            }
        }
        for (int i = 0; i<pn && pt[i]*n<=mx; ++i) {
            int k = pt[i];
            while (mx >= n*k) {
                for (int j = n; j*k < mx; ++j) if (GET(j*k)) SET(j);
                k *= pt[i];
            }
        }
        for (int i = n; i <= mx+1; ++i) if (!GET(i)) {
            printf("%d
    ", i);
            break;
        }
        
        return 0;
    }
  • 相关阅读:
    [转]Flex PieChart
    Flash Builder 4 下载
    [转]Android如何防止apk程序被反编译
    [转]自定义Spinner五步走
    [转]coolpad 获得 root
    [转]c# .net 用程序画图 曲线图
    android ContentProvider 遭遇 failed to find provider info
    [转]如何把多个Android Project打包成一个APK
    android loading界面 及 处理
    [转]android中生成和使用jar 分享
  • 原文地址:https://www.cnblogs.com/txd0u/p/3450361.html
Copyright © 2011-2022 走看看