const int MAX_N = 1e3 + 50;
int N, K;
int mat[MAX_N][MAX_N];
void work(int len) {
if (2 * len > MAX_N)//1024即可
return;
for (int i = 1; i <= len; i++) {
for (int j = 1; j <= len; j++) {
mat[i + len][j] = mat[i][j] + len;//构造左同大小矩阵
mat[i + len][j + len] = mat[i][j];//构造斜左下同大小矩阵
mat[i][j + len] = mat[i][j] + len;//构造下同大小矩阵
}
}
work(2 * len);//扩大规模
}
void init() {
mat[1][1] = 1; mat[1][2] = 2;
mat[2][1] = 2; mat[2][2] = 1;
work(2);
}
bool check() {//检查前k行是否有出现大于N的数出现
for (int i = 2; i <= K + 1; i++) {
for (int j = 1; j <= N; j++) {
if (mat[i][j] > N) {
return false;
}
}
}
return true;
}
int lowbit(int x) {
return x & (-x);//-x = ~x + 1
}
int main() {
//while (~scanf("%d", &N))
//printf("%d\n", lowbit(N));
init();
int T;
cin >> T;
while (T--) {
scanf("%d%d", &N, &K);
//bool ok = check();
if (K >= lowbit(N)) {//直接用lowbit判断
puts("Impossible");
continue;
}
for (int i = 2; i <= K + 1; i++)
for (int j = 1; j <= N; j++)
printf("%d%c", mat[i][j], j == N ? '\n' : ' ');
}
}
问题转化为找到m个二阶置换{f_i},使得对于任意i!=j都有f_i(a)!=f_j(a)且f_i(f_j(a))=f_j(f_i(a))。
再想一想异或的性质。?
真的牛
int n, m, k;
int main(){
int T, cas = 1;
scanf("%d", &T);
while (T--){
scanf("%d%d", &n, &m);
if (m >= (n & (-n))) { puts("Impossible"); continue; }
for (int j = 1; j <= m; j++)
for (int i = 0; i < n; i++)
printf("%d%c", (i ^ j) + 1, i == n - 1 ? '\n' : ' ');
}
return 0;
}