Zoj 4063(构造题 思维题)

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;
}


上一篇:ZOJ-3869,Ace of Aces(简单题)


下一篇:ACM入门-ZOJ 1383 Binary Numbers 二进制数