题意:从1-n*n里取数去填n*n个格子,使得每一行每一列以及对角线都不相同
思路:有两种方法
第一:直接在n*n-1中依次填上数,最后在最后一列里再一次填上
1 2 3 13
4 5 6 14
7 8 9 15
10 11 12 16
第二:随机构造,每次交换两数,使得满足条件
代码一:
#include <stdio.h>
#include <cstring>
#include <time.h>
#include <set>
using namespace std;
int m[205][205];
int main()
{
int t,n,g=1;
scanf("%d",&t);
while(t--)
{
int num=1;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
m[i][j]=num++;
}
for(int i=1;i<=n;i++)
m[i][n]=num++;
printf("Case #%d:\n",g++);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(j==n)
printf("%d\n",m[i][j]);
else
printf("%d ",m[i][j]);
}
}
}
return 0;
}
代码二:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <set>
using namespace std;
#define maxn 210
int a[maxn][maxn];
int n;
int judge()
{
int i,j,sum;
set<int> s;
for(i=1; i<=n; i++)
{
sum=0;
for(j=1; j<=n; j++)
sum+=a[i][j];
s.insert(sum);
sum=0;
for(j=1; j<=n; j++)
sum+=a[j][i];
s.insert(sum);
}
sum=0;
for(i=1; i<=n; i++)
sum+=a[i][i];
s.insert(sum);
sum=0;
for(i=1; i<=n; i++)
sum+=a[i][n-i+1];
s.insert(sum);
return s.size();
}
int main()
{
int i,j,tem,T,cas;
int x1,x2,y1,y2;
scanf("%d",&T);
for(cas=1; cas<=T; cas++)
{
scanf("%d",&n);
printf("Case #%d:\n",cas);
for(i=1; i<=n; i++)
for(j=1; j<=n; j++)
a[i][j]=(i-1)*n+j;
srand((unsigned)time(NULL));
while(1)
{
for(i=1; i<=n; i++) //次数随便设置
{
x1=rand()%n+1;
y1=rand()%n+1;
x2=rand()%n+1;
y2=rand()%n+1;
tem=a[x1][y1];
a[x1][y1]=a[x2][y2];
a[x2][y2]=tem;
}
if (judge()==2*n+2)break;
}
for(i=1; i<=n; i++)
{
for(j=1; j<n; j++)
printf("%d ",a[i][j]);
printf("%d\n",a[i][n]);
}
}
return 0;
}