题目:Elegant Square
题目大意:输出一个n*n的,各个数不同的,各个数没有平方因子的,各行各列累积相同的矩阵。
题解:
答案矩阵的元素为两组质数相互组合的积
选两组不同的相互错排的矩阵,
答案矩阵为两个错排矩阵对应质数的积。
但偶数情况下,两组错排是不够的,所以加多一组质数。
大概因为像4 6这种比自己小一半而且还跟本身互质的数不超过两个,很难用两组错排矩阵,构造没有相同元素的答案矩阵。(口胡)
下面是我对于6的三组错排矩阵构造方法(规律比较好找,大概)
/*
以6为例
1 2 3 4 5 6
2 3 4 5 6 1
3 4 5 6 1 2
4 5 6 1 2 3
5 6 1 2 3 4
6 1 2 3 4 5
1 2 3 4 5 6
6 5 4 3 2 1
5 4 3 2 1 6
4 3 2 1 6 5
3 2 1 6 5 4
2 1 6 5 4 3
1 3 5 2 4 6
3 5 2 4 6 1
5 2 4 6 1 3
2 4 6 1 3 5
4 6 1 3 5 2
6 1 3 5 2 4
*/
#include <iostream>
#include <cstdio>
#include <vector>
#include <cstdlib>
#include <set>
using namespace std;
typedef long long ll;
vector<int> a[5];
int p[1100],k;
bool b[1100];
int ans[50][50];
int xu[50];//差分为2的排列
void getp()//线性筛
{
for(int i=2;i<=1000;i++)
{
if(!b[i]) p[k++]=i;
for(int j=0;j<k&&p[j]*i<=1000;j++)
{
b[p[j]*i]=1;
if(i%p[j]==0) break;
}
}
}
int main()
{
getp();
freopen("elegant.in","r",stdin);
freopen("elegant.out","w+",stdout);
int n;scanf("%d",&n);
int kk=0;
for(int i=0;i<3;i++) for(int j=0;j<n;j++) a[i].push_back(p[kk++]);//存点质数来用
if(n%2==0) for(int i=0;i+i<n;i++) xu[i]=i+i,xu[i+n/2]=i+i+1;//前半和后半差分为2的排列
for(int i=0;i<n;i++)
{
if(i==0) kk=0;
else kk=n-i;
for(int j=0;j<n;j++)
{
ans[i][j]=a[0][(i+j)%n]*a[1][(kk+j)%n];
if(n%2==0) ans[i][j]*=a[2][(xu[j]+i)%n];//偶数情况乘多第三组
printf("%d",ans[i][j]);
if(j+1==n) putchar('\n');
else putchar(' ');
}
}
return 0;
}