题目链接:Hack It
题意
构造一个 n×n (1≤n≤2000) n × n ( 1 ≤ n ≤ 2000 ) 的 01 01 矩阵,要求矩阵内的 1 1 的个数不小于 且对于矩阵内任意一个子矩阵,子矩阵中的四个角的数字不同时为 1 1 。
输入
无。
输出
第一行为一个整数 ,表示将要输出的矩阵大小,接下来 n n 行 列的字符串,字符串内每个字符只能为 0 0 或者 。
样例
输入 |
---|
输出 |
3 010 000 000 |
提示 |
显然这个输出并不合法,只是为了说明输出格式。 |
题解
关于构造方法的证明思路,不会,详见大佬给出的证明(也可以直接跳过证明看构造的方法):
![]()
文字描述构造方案比较麻烦,直接看图找规律比较好些,构造方案如下( 的情况下):
1000100010001000010001000100010000100010001000100001000100010001100001000010000101000010000110000010000110000100000110000100001010000010100000100100000101000001001010000010100000010100000101001000000100100100010010000001001000100100100000010001001001001000 1000 1000 1000 1000 1000 0100 0010 0001 1000 0010 1000 0010 1000 0001 0010 0100 0100 0100 0100 0100 0100 0010 0001 1000 0100 0001 0100 0001 0100 1000 0001 0010 0010 0010 0010 0010 0010 0001 1000 0100 0010 1000 0010 1000 0010 0100 1000 0001 0001 0001 0001 0001 0001 1000 0100 0010 0001 0100 0001 0100 0001 0010 0100 1000
于是对于 2000×2000 2000 × 2000 的情况,找到子矩阵大小为 47×47 47 × 47 的就可以满足条件,将多出 2000 2000 的部分截断即可。过题代码
#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; }