zoukankan      html  css  js  c++  java
  • agc027D

    题意

    题目链接

    构造一个(n * n)的矩阵,要求任意相邻的两个数(a,b),使得(max(a,b) \% min(a,b) ot = 0)

    Sol

    我的思路:

    假设(mod = 1),那么可以在第一行放2 3 4 5 (dots),第一列同理也这样放

    对于任意位置(i),一定满足要求的一个数是a[i - 1][j] * a[i][j - 1] / __gcd(a[i - 1][j], a[i][j - 1]) + 1

    然而最后的数大到上天啊。。。

    标算挺巧妙的,首先把整个图黑白染色,那么同色点之间是互不影响的。

    考虑构造(mod = 1)的矩阵。

    若白点的权值确定了,那么黑点的权值应当是所有相邻白点的(lcm)+1,

    那所有白点的权值怎么确定呢?

    考虑直接用素数填充对于正对角线和负对角线上的每个点分配一个不同的素数

    那么任意白点的权值为所在正对角线上的素数 乘 负对角线的素数

    这样算出来最大的$a_{ij} = 414556486388264 $,满足要求

    不过为啥数组要开1000才能过???

    
    #include<bits/stdc++.h>
    #define int long long 
    using namespace std;
    const int MAXN = 1e5 + 10;
    int N;
    int a[1001][1001], vis[MAXN], prime[MAXN], tot;
    void GetPhi() {
    	vis[1] = 1;
    	for(int i = 2; i; i++) {
    		if(!vis[i]) prime[++tot] = i;
    		if(tot == 1000) break; 
    		for(int j = 1; j <= tot && (i * prime[j] <= 10000); j++) {
    			vis[i * prime[j]] = 1;
    			if(!(i % prime[j])) break;
    		}
    	}
    }
    int lcm(int x, int y) {
    	if(x == 0 || y == 0) return x + y;
    	return x / __gcd(x, y) * y;
    }
    main() {
    	GetPhi();
    	cin >> N;
    	if(N == 2) {
    		printf("4 7
    23 10");
    		return 0;
    	}
    	for(int i = 1; i <= N; i++) 
    		for(int j = 1; j <= N; j++)
    			if(!((i + j) & 1)) a[i][j] = prime[(i + j) / 2] * prime[N + (i - j) / 2 + (N + 1) / 2];
    	for(int i = 1; i <= N; i++)
    		for(int j = 1; j <= N; j++)
    			if(!a[i][j]) 
    				a[i][j] = lcm(lcm(a[i - 1][j], a[i][j - 1]), lcm(a[i][j + 1], a[i + 1][j])) + 1;
    	for(int i = 1; i <= N; i++, puts(""))
    		for(int j = 1; j <= N; j++)
    			cout << a[i][j] << " ";
    	return 0;
    }
    
  • 相关阅读:
    S3C2440的LCD虚拟显示测试
    arm-linux-gcc编译器测试
    韦东山教程ARM的时钟设置出现的问题及其解决方法
    程序在nor flash中真的可以运行吗?
    存储器的速度
    程序测试的方法
    对编程的一些思考

    [算法题] 字节流解析
    [C/C++]函数指针和函数分发表
  • 原文地址:https://www.cnblogs.com/zwfymqz/p/9718849.html
Copyright © 2011-2022 走看看