题目链接:Hack It
题意
构造一个 的 矩阵,要求矩阵内的 的个数不小于 且对于矩阵内任意一个子矩阵,子矩阵中的四个角的数字不同时为 。
输入
无。
输出
第一行为一个整数 ,表示将要输出的矩阵大小,接下来 行 列的字符串,字符串内每个字符只能为 或者 。
样例
输入 |
---|
输出 |
3 010 000 000 |
提示 |
显然这个输出并不合法,只是为了说明输出格式。 |
题解
关于构造方法的证明思路,不会,详见大佬给出的证明(也可以直接跳过证明看构造的方法):
文字描述构造方案比较麻烦,直接看图找规律比较好些,构造方案如下( 的情况下):
于是对于 的情况,找到子矩阵大小为 的就可以满足条件,将多出 的部分截断即可。
过题代码
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <cstring>
#include <string>
#include <vector>
#include <list>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <bitset>
#include <algorithm>
#include <sstream>
using namespace std;
#define LL long long
const int n = 47;
const int maxn = n * n + 100;
char str[maxn][maxn];
int main() {
#ifdef Dmaxiya
freopen("test.txt", "r", stdin);
#endif // Dmaxiya
ios::sync_with_stdio(false);
memset(str, '0', sizeof(str));
for(int i = 0; i < n; ++i) {
for(int j = 0; j < n; ++j) {
str[i][j * n + (i * j) % n] = '1';
}
}
for(int i = 1; i < n; ++i) {
for(int j = 0; j < n; ++j) {
for(int k = 0; k < n; ++k) {
for(int l = 0; l < n; ++l) {
str[i * n + j][k * n + l] = str[(i - 1) * n + j][k * n + ((l - 1) % n + n) % n];
}
}
}
}
printf("2000\n");
for(int i = 0; i < 2000; ++i) {
str[i][2000] = '\0';
printf("%s\n", str[i]);
}
return 0;
}