zoukankan      html  css  js  c++  java
  • CF#303A Lucky Permutation Triple 数论

    题意:要求给出一个数N的余数系的三个排列A, B, C,其中使得对于任意的 i 满足(A[i] + B[i]) % N = C[i]。

    例如N=5的时候有一下排列:

    A: 1 4 3 2 0
    B: 1 0 2 4 3
    C: 2 4 0 1 3

    解法:首先排列如果存在的话,肯定是不唯一的,因为可以随意交换A,B,C的相同两列使得结果仍然满足。对于一个给定的N,我们可以列出一下一张图:

    横纵坐标反应了余数相加的情况:
    0 1 2 3 4
    1 2 3 4 0
    2 3 4 0 1
    3 4 0 1 2
    4 0 1 2 3
    只要取从左上到右下的对角线即可。

    以上只能够保证N为奇数的时候有解,不足以说明白偶数为何无解。还有一种观点现在自己还证不出来:对于每一种合法的情况,A,B,C一定是按照某种规则增长的,也就是一个等差数列,只是每一位数都对N取模而已。那么如果公差d于N互质的话,能够在N步之内枚举完所有的余数,否则不能。

    证:任何一个序列如果从0开始,那么序列就变为了0, d%N, 2*d%N ... i*d%N ... j*d%N...(N-1)*d%N 如果存在id % N = jd % N,那么N | (j-i)d,由于gcd(d, N) = 1 且 i-j < N,这显然是荒谬的。所以任意两个id%N, jd%N都是互质的,因为有N个数,所以也就取遍了所有的余数,而对于于N不互质的d,则无法推导出次结论,实际上只要 j-i = N/gcd(d,N)时,就有id%N = jd%N了,显然可以找到这样两个余数相同的数。

    这也就是为什么上面取A,B序列公差均为1可以的原因了,因为两个公差为1的序列相加之后公差为2,而2与奇数N是互质的。因此还可以选择更多的方案来完成匹配。如果上面的假设成立,那么对于偶数N也是很好否定的,因为偶数N的A,B所取得两个公差一定要求都是奇数,而如此对于C而言则公差变成了偶数,此时N也为偶数,由于d于N不互质,也就无法构造出这样三个序列了。

    现在我无法证明的就是为什么在对A做一个排序使其成为d=1的序列后,一定要求B也同样为一个等差序列。

    代码如下:

    #include <cstdlib>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    
    int main() {
        int N;
        while (scanf("%d", &N) != EOF) {
            if (!(N&1)) {
                puts("-1");
                continue;    
            }
            for (int i = 0; i < N; ++i) {
                printf(i == N-1 ? "%d\n" : "%d ", i);
            }
            for (int i = 0; i < N; ++i) {
                printf(i == N-1 ? "%d\n" : "%d ", i);
            }
            for (int i = 0; i < N; ++i) {
                printf(i == N-1 ? "%d\n" : "%d ", 2*i%N);
            }
        }
        return 0;    
    }
  • 相关阅读:
    安装IIS的郁闷之旅
    设置WPF窗口相对于非WPF窗口的位置
    钓鱼记
    java拾遗
    人间四月芳菲尽
    [linux] x server can not start under VMWare
    如果没有开源软件没有免费软件,这个世界会怎么样?评[盖茨北大演讲遭遇开源人士抗议]
    程序员的面包
    2007中国软件英雄会-七年的等待
    sysbench安装
  • 原文地址:https://www.cnblogs.com/Lyush/p/3075939.html
Copyright © 2011-2022 走看看