比赛链接:https://www.nowcoder.com/acm/contest/201#question
如果你希望解锁Miyuki的手机,你需要回答30个问题,只有你非常关注Miyuki才能全部解答正确。而且,根据“你”的不同,Miyuki的行为也是不一样的,对于不同的"你",答案相同的概率为。可以说,对于每个不同的"你",都有一个唯一的Miyuki。
不过因为Miyuki现在心情很好,所以你只需要回答一个问题。给一个正整数 n,要求构造一个 n x n 的方阵 A,使得方阵的每一行,每一列都分别是一个 的排列,并且对于所有的 1 ≤ i < j ≤ n, 有 Ai,j ≠ Aj,i。
有解输出任意一个方案,否则输出“-1”(不含引号)。
该代码使用了搜索的思想,如果是奇数的话直接对角线输出,偶数的话可以有多个奇数块来组成,4的方阵要自己写,2的时候输出-1
#include<bits/stdc++.h> using namespace std; const int N=1005; int s[N][N]; void dfs(int n) { if(n==4){ s[1][1]=1;s[1][2]=4;s[1][3]=3;s[1][4]=2; s[2][1]=2;s[2][2]=3;s[2][3]=4;s[2][4]=1; s[3][1]=4;s[3][2]=1;s[3][3]=2;s[3][4]=3; s[4][1]=3;s[4][2]=2;s[4][3]=1;s[4][4]=4; return; } if(n&1){ for(int i=1;i<=n;i++) s[1][i]=i; for(int i=2;i<=n;i++){ for(int j=1;j<=n;j++){ if(j==1) s[i][j]=s[i-1][n]; else s[i][j]=s[i-1][j-1]; } } return; } dfs(n>>1); for(int i=1;i<=n/2;i++) for(int j=n/2+1;j<=n;j++) s[i][j]=s[i][j-n/2]+n/2; for(int i=n/2+1;i<=n;i++){ for(int j=n/2+1;j<=n;j++) s[i][j]=s[i-n/2][j-n/2]; } for(int j=1;j<=n/2;j++){ for(int i=n/2+1;i<=n;i++){ if(j==n/2){ s[i][j]=s[1][i]; } else s[i][j]=s[j+1][i]; } } } int main() { int n; cin>>n; if(n==1){ cout<<1<<endl; return 0; } else if(n==2){ cout<<"-1"<<endl; return 0; } else if(n&1){ for(int i=1;i<=n;i++) s[1][i]=i; for(int i=2;i<=n;i++){ for(int j=1;j<=n;j++){ if(j==1) s[i][j]=s[i-1][n]; else s[i][j]=s[i-1][j-1]; } } } else{ dfs(n); } for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ cout<<s[i][j]<<(j==n?" ":" "); } } return 0; }