AtCoder Grand Contest 027 D - Modulo Matrix

AtCoder Grand Contest 027 D - Modulo Matrix_第1张图片

题目大意

构造一个 n ∗ n n*n nn的矩阵
要求满足:
1、任意相邻的两个元素(可以上下可以左右)都满足 a m a x % a m i n = m a_{max}\%a_{min}=m amax%amin=m(其中 m m m是任意的一个整数, a m a x a_{max} amax是元素中较大的数, a m i n a_{min} amin是较小的数)
2、对于任意元素 a a a满足: a < 1 0 15 a<10^{15} a<1015
3、对于任意两元素 a , b a,b a,b满足 a ! = b a!=b a!=b

思考历程

可以像国际象棋一样染色一下,同色之间则不会相互影响。
我的构造比较猎奇,直接把一条中间的那一条给取出来后,直接每次乘上一个质数,然后再衍生取出即可。
然鹅这样构造会超过 1 0 15 10^{15} 1015

题解

其实一开始是对的,黑白棋染色。
考虑直接钦定 m = 1 m=1 m=1
现在假设把黑色块取出来(白色一样的),然后可以把斜着的方块转正一下,那么考虑每一行每一列都对应一个不同的质数,然后当前格子的答案即为当前行对应的质数乘上当前列对应的质数。
稍微调整一下质数对应的位置就可以保证小于 1 0 15 10^{15} 1015,然后白格子就直接取周围黑格子的lcm再 + 1 +1 +1就构造完成了。

代码

#include 
#include 
#include 
#include 
using namespace std;
 
bool bz[500010];
int gs,n;
long long b[1010][1010],c[1010][1010],ans[1010][1010],zs[500010];
int fx[4][2]={
     {
     0,-1},{
     0,1},{
     -1,0},{
     1,0}};
 
long long gcd(long long a,long long b)
{
     
	if (b==0) return a;
	return gcd(b,a%b);
}
 
long long lcm(long long x, long long y) 
{
     
	if (x==0 || y==0) return x+y;
	return x/gcd(x,y)*y;
}
 
int main()
{
     
	for (int i=2;i<=500000;i++)
	{
     
		if (!bz[i])
		{
     
			gs++;
			zs[gs]=i;
			for (int j=1;j<=500000/i;j++)
			{
     
				bz[j*i]=true;
			}
		}
	}
	scanf("%d",&n);
	if (n==2)
	{
     
		printf("4 7\n");
		printf("23 10\n");
		return 0;
	}
	for (int i=1;i<=n;i++)
	{
     
		if (i%2==1)
		{
     
			int x=1;int y=i;
			while (x<=n && y<=n)
			{
     
				b[x][y]=zs[i];
				x++;y++;
			}
			if (i==1) continue;
			x=i;y=1;
			while (x<=n && y<=n)
			{
     
				b[x][y]=zs[i-1];
				x++;y++;
			}
		}
	}
	for (int i=n;i>=1;i--)
	{
     
		if (i%2==1)
		{
     
			int x=1;int y=i;
			while (x<=n && y>=1)
			{
     
				c[x][y]=zs[n+n-i+1];
				x++;y--;
			}
			if (i==n) continue;
			if (n%2==0) x=n-i+1;
			else x=n-i+1;y=n;
			while (x<=n && y>=1)
			{
     
				c[x][y]=zs[n+n-i];
				x++;y--;
			}
		}
	}
	for (int i=1;i<=n;i++)
	{
     
		for (int j=1;j<=n;j++)
		{
     
			if ((i+j)%2==0)
			{
     
				ans[i][j]=b[i][j]*c[i][j];
			}
		}
	}
	for(int i = 1; i <= n; i++)
	{
     
		for(int j = 1; j <= n; j++)
		{
     
			if(!ans[i][j]) 
			{
     
				ans[i][j]=lcm(lcm(ans[i-1][j],ans[i][j-1]),lcm(ans[i][j+1],ans[i+1][j]))+1;
			}
		}
	}
	for (int i=1;i<=n;i++)
	{
     
		for (int j=1;j<=n;j++)
		{
     
			printf("%lld ",ans[i][j]);
		}
		printf("\n");
	}
}

你可能感兴趣的:(atcoder)