• CCPC-WannaFly-Camp 1057: Kimi to Kanojo to Kanojo no Koi(構造)


    时间限制: 1 Sec  内存限制: 1024 MB  Special Judge

    如果你希望解锁美雪的手机,你需要回答30个问题,只有你非常关注美雪才能全部解答正确。而且,根
    据"你"的不同,美雪的行为也是不一样的。对于不同的"你",答案相同的概率为3130。可以说,对于每个
    不同的"你",都有一个唯一的美雪。
    不过因为美雪现在心情很好,所以你只需要回答一个问题。给一个正整数n,请你输出一个n × n 的
    方阵A,满足方阵的每一行,每一列都是一个1 ∼ n 的排列,并且对于所有的1 ≤ i < j ≤ n, 有
    Ai,j ̸= Aj,i。
    有解输出任意一个方案,否则输出“-1”(不含引号)。

    Input
    输入仅一行一个整数n(1 ≤ n ≤ 1000)。
    Output
    如果有解,输出n 行,每行n 个[1, n] 范围内的整数,第i行第j个数表示Ai,j;否则输出“-1”。
    Example
    standard input

    3

    standard output
    1 3 2
    2 1 3
    3 2 1

    题解:

    有三种情况:
    1、n 是奇数,我们可以构造如下的方阵:
    1, 2, 3, ... n-2, n-1, n
    n, 1, 2, ... n-3, n-2, n-1
    ...
    3, 4, 5, ... n, 1, 2
    2, 3, 4, ... n-1, n, 1
    可知对于所有的i,j (1<=i<j<=n), A[i][j]+A[j][i]=n+2, 所以A[i][j] 不可能等于A[j][i]。
    2、n=2,无解。
    3、n 为大于2 的偶数:当n = 4 的时候,有这样一组解:
    1, 2, 3, 4
    4, 3, 2, 1
    2, 1, 4, 3
    3, 4, 1, 2
    当n>4 的时候,我们假设n=2k (k>2), 并且当n=k 时存在一组合法解,那么我们构造n=2k 时的解:
    记A(t) 为n=t 时的一组解。首先,我们先令A(2t) 为:
    A(k), A(k)
    A(k), A(k)
    之后, 我们在左上和右下的A(k) 中给所有元素加上k:
    A(k)+k, A(k)
    A(k), A(k)+k
    之后,我们把右上的A(k) 沿着它的主对角线翻转一下并记为A’(k),此时我们可以得到:对于所有在
    A’(k) 中的A(2k)[i][j],有A(2k)[i][j] = A(2k)[j][i],具体如下。
    A(k)+k, A’(k)
    A(k), A(k)+k
    最后, 我们只要把左下的A(k) 的值都移一位就好。(1->2, 2->3, ..., k->1):
    A(k)+k, A’(k)
    A(k)+1, A(k)+k
    这样n=2k 的解就构造出来了。

    #include <cstdio>
    #include <vector>
     
    using namespace std;
     
    const int MAXN = 1005;
     
    int board[MAXN][MAXN];
     
    inline void BuildFour(){
        board[1][1] = 1;
        board[1][2] = 2;
        board[1][3] = 3;
        board[1][4] = 4;
        for(int i=1 ; i<=4 ; ++i)board[2][i] = 4+1-board[1][i];
        board[3][1] = 2;
        board[3][2] = 1;
        board[3][3] = 4;
        board[3][4] = 3;
        for(int i=1 ; i<=4 ; ++i)board[4][i] = 4+1-board[3][i];
    }
     
    inline void BuildOdd(int i){
        int sum = (i*(i+1))/2;
        for(int j=1 ; j<=i ; ++j){
            int t = j;
            for(int k=1 ; k<=i ; ++k){
                board[k][t] = j;
                ++t;
            }
        }
        for(int j=2 ; j<=i ; ++j){
            int tt = 0;
            for(int k=2 ; k<=i ; ++k)tt += board[j][k];
            int t = 1;
            for(int k=j ; k<=i ; ++k){
                board[k][t] = sum - tt;
                ++t;
            }
        }
    }
     
    inline void BuildEven(int x){
        int t = x;
        while(t%2 == 0 && t != 4)t /= 2;
        if(t == 4){
            BuildFour();
        }
        else {
            BuildOdd(t);
        }
        for(int i=t ; i<x ; i*=2){
            for(int j=i+1 ; j<=i*2 ; ++j){
                for(int k=i+1 ; k<=i*2 ; ++k){
                    board[j][k] = board[j-i][k-i]+i;
                }
            }
            for(int j=1 ; j<=i ; ++j){
                for(int k=i+1 ; k<=i*2 ; ++k){
                    board[j][k] = board[k-i][j];
                }
            }
            for(int j=i+1 ; j<=i*2 ; ++j){
                for(int k=1 ; k<=i ; ++k){
                    board[j][k] = board[j-i][k]+1;
                    if(board[j][k] == i+1)board[j][k] = 1;                  
                }
            }
            for(int j=1 ; j<=i ; ++j){
                for(int k=1 ; k<=i ; ++k)
                    board[j][k] += i;
            }                  
        }
    }
     
    inline void Print(int x){
        for(int i=1 ; i<=x ; ++i){
            for(int j=1 ; j<x ; ++j)printf("%d ",board[i][j]);
            printf("%d
    ",board[i][x]);
        }
    }
     
     
    int main(){
         
        int N;
        while(scanf("%d",&N) == 1){
            if(N == 1)printf("1
    ");
            else if(N == 2)printf("-1
    ");
            else if(N&1){
                BuildOdd(N);
                Print(N);
            }
            else {
                BuildEven(N);
                Print(N);
            }
        }
         
        return 0;
    }
     
     
    //
    //1 2 3 4
    //4 3 2 1
    //2 1 4 3
    //3 4 1 2
    // 
    /**************************************************************
        Problem: 1057
        User: 2016203524
        Language: C++
        Result: 正确
        Time:252 ms
        Memory:4904 kb
    ****************************************************************/
  • 相关阅读:
    数据库之多表操作
    数据库之修改表结构
    mysql数据库
    协程
    线程
    Javaweb基础学习—— jQuery基础
    javaweb基础学习—— css
    JDBC基础学习笔记
    JDBC连接MySQL常见错误集锦
    MySQL基础笔记
  • 原文地址:https://www.cnblogs.com/vocaloid01/p/9514018.html
Copyright © 2020-2023  润新知