nowcoder Kimi to Kanojo to Kanojo no Koi
如果你希望解锁Miyuki的手机,你需要回答30个问题,只有你非常关注Miyuki才能全部解答正确。而且,根据“你”的不同,Miyuki的行为也是不一样的,对于不同的"你",答案相同的概率为。可以说,对于每个不同的"你",都有一个唯一的Miyuki。
不过因为Miyuki现在心情很好,所以你只需要回答一个问题。给一个正整数 n,要求构造一个 n x n 的方阵 A,使得方阵的每一行,每一列都分别是一个 的排列,并且对于所有的 1 ≤ i < j ≤ n, 有 Ai,j ≠ Aj,i。
有解输出任意一个方案,否则输出“-1”(不含引号)。
输入描述:
输入仅一行一个整数 n(1 ≤ n ≤ 1000)。
输出描述:
如果有解,输出 n 行,每行 n 个 [1,n] 范围内的整数,第i行第j个数表示 Ai,j;否则输出"-1"。
示例1
输入
复制
3
输出
复制
1 3 2
2 1 3
3 2 1
分为一下几种情况
1.n 为 奇数
1 7 6 5 4 3 2
2 1 7 6 5 4 3
3 2 1 7 6 5 4
4 3 2 1 7 6 5
5 4 3 2 1 7 6
6 5 4 3 2 1 7
7 6 5 4 3 2 1
找规律,直接类似于于这种形式进行构造
2.n 为 2 的指数,n = 2 输出-1,否则:
先构造出n = 4
1 2 3 4
3 4 1 2
4 3 2 1
2 1 4 3
设其为A4
A8 = A4 (A4+4)
(A4+4)转置 A4
1 2 3 4 5 6 7 8
3 4 1 2 7 8 5 6
4 3 2 1 8 7 6 5
2 1 4 3 6 5 8 7
6 8 7 5 1 2 3 4
5 7 8 6 3 4 1 2
8 6 5 7 4 3 2 1
7 5 6 8 2 1 4 3
A16 = A8.....
3.n 为偶数
先找到其所对应的奇数x,不断除以2
先构造出Ax,再构造出A2x
A2x = Ax (Ax+x)轮换一个单位
Ax的对称 Ax
然后 A4x = A2x (A2x+2x)
(A2x+2x)转置 A2x
例如 n = 12 x = 3
A3 =
1 3 2
2 1 3
3 2 1
A6 =
1 3 2 6 5 4
2 1 3 4 6 5
3 2 1 5 4 6
4 5 6 1 3 2
6 4 5 2 1 3
5 6 4 3 2 1
A12 =
1 3 2 6 5 4 7 9 8 12 11 10
2 1 3 4 6 5 8 7 9 10 12 11
3 2 1 5 4 6 9 8 7 11 10 12
4 5 6 1 3 2 10 11 12 7 9 8
6 4 5 2 1 3 12 10 11 8 7 9
5 6 4 3 2 1 11 12 10 9 8 7
11 12 10 9 8 7 1 3 2 6 5 4
12 10 11 8 7 9 2 1 3 4 6 5
10 11 12 7 9 8 3 2 1 5 4 6
9 8 7 11 10 12 4 5 6 1 3 2
8 7 9 10 12 11 6 4 5 2 1 3
7 9 8 12 11 10 5 6 4 3 2 1
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5+10;
const ll inf = 99999999999;
int fun(int x)
{
if(x == 2 || x%2 == 1) return x;
return fun(x/2);
}
int a[1005][1005];
int main()
{
int n;
cin >> n;
if(n == 2) {cout << -1 << endl;return 0;}
int fn = fun(n);
int p;
if(fn%2==1)
{
int t = fn;
p = fn*2;
for(int i = 1; i <= fn; i++)
for(int j = i+1; j <= fn; j++)
a[i][j] = fn-(j-i)+1;
for(int i = 1; i <= fn; i++)
for(int j = 1; j <= i; j++)
a[i][j] = i-j+1;
for(int i = t+1; i <= t+t; i++)
for(int j = t+1; j <= t+t; j++)
a[i][j] = a[i-t][j-t];
for(int i = 1; i <= t; i++)
for(int j = t+1; j <= t+t; j++)
a[i][j] = a[i][max(1,(j-t+1)%(t+1))]+t;
for(int i = t+1; i <= t+t; i++)
for(int j = 1; j <= t; j++)
a[i][j] = a[j][i-t]+t;
}
if(fn == 2)
{
a[1][1] = a[2][3] = a[3][4] = a[4][2] = 1;
a[1][2] = a[2][4] = a[3][3] = a[4][1] = 2;
a[1][3] = a[2][1] = a[3][2] = a[4][4] = 3;
a[1][4] = a[2][2] = a[3][1] = a[4][3] = 4;
p = 4;
}
for(int t = p; t < n; t*=2)
{
for(int i = t+1; i <= t+t; i++)
for(int j = t+1; j <= t+t; j++)
a[i][j] = a[i-t][j-t];
for(int i = 1; i <= t; i++)
for(int j = t+1; j <= t+t; j++)
a[i][j] = a[i][j-t]+t;
for(int i = t+1; i <= t+t; i++)
for(int j = 1; j <= t; j++)
a[i][j] = a[t-j+1][i];
}
for(int i = 1; i <= n; i++)
{
for(int j = 1; j < n; j++)
{
cout << a[i][j] << " ";
}
cout << a[i][n] << endl;
}
return 0;
}