AtCoder Grand Contest 027D - Modulo Matrix(构造)
AtCoder Grand Contest 027D - Modulo Matrix
题目大意
- 要求构造一个 n ∗ n n*n n∗n的元素互异且值域为小于等于 1 0 15 10^{15} 1015正整数的矩阵,要求满足任意相邻两个数 x , y x,y x,y满足 m a x ( x , y ) m o d m i n ( x , y ) = m max(x,y) \mod min(x,y)=m max(x,y)modmin(x,y)=m,其中正整数 m m m为某个不确定的定值。
- n ≤ 500 n≤500 n≤500
题解
- 可以先把相邻的格子黑白染色,那么同种颜色之间没有干扰,
- 一种最简单的构造是把所有黑格按正整数从小到大赋值,接着每个白格的值即为它相邻黑格的 l c m lcm lcm加上某个常数(比如是 1 1 1),但这样值域最坏大概为 ( n 2 ) 4 (n^2)^4 (n2)4级别,超过了限制。
- 考虑怎样才能使值域减小,或者说考虑怎样才能使每个白格相邻的黑格的 l c m lcm lcm最小,
- 用如下方式构造,使黑格所在的每条对角线对应一个质数,那每个黑格的值就是它所在的两条交叉对角线对应的质数之积,而白格和上面一样,
- 这样可以使 l c m lcm lcm降到 n 4 n^4 n4级别,在值域的范围内。
- 至于为什么要选择质数?
- 很显然,若不选质数会存在有两数相等的情况。
代码
#include<cstdio>
#include<cstring>
using namespace std;
#define N 510
#define ll long long
int a[4 * N], p[100 * N];
ll sx[N][N], sy[N][N];
int main() {
int n, i, j, s = 0;
scanf("%d", &n);
for(i = 2; i; i++) if(!p[i]) {
a[++s] = i;
if(s == 4 * n) break;
for(j = 1; j * i < 100 * N; j++) p[i * j] = 1;
}
int t = 0;
for(i = 0; i <= n + 1; i += 2) {
t++;
int x = i, y = 0;
while(x <= n + 1 && y <= n + 1) sx[x][y] = a[t], x++, y++;
}
for(i = 2; i <= n + 1; i += 2) {
t++;
int x = 0, y = i;
while(x <= n + 1 && y <= n + 1) sx[x][y] = a[t], x++, y++;
}
if(n % 2 == 0) i = n; else i = n + 1;
for(i; i >= 0; i -= 2) {
t++;
int x = i, y = 0;
while(x >= 0 && y <= n + 1) sy[x][y] = a[t], x--, y++;
}
if(n % 2 == 0) i = 1; else i = 2;
for(i; i <= n + 1; i++) {
t++;
int x = n + 1, y = i;
while(x >= 0 && y <= n + 1) sy[x][y] = a[t], x--, y++;
}
for(i = 1; i <= n; i++) {
for(j = 1; j <= n; j++) {
if(sx[i][j]) printf("%lld ", sx[i][j] * sy[i][j]);
else printf("%lld ", sx[i][j - 1] * sx[i - 1][j] * sy[i - 1][j] * sy[i][j + 1] + 1);
}
printf("\n");
}
return 0;
}
哈哈哈哈哈哈哈哈哈哈
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现