1723: 感恩节KK专场——陪学妹上课
时间限制: 1 Sec 内存限制: 128 MB提交: 56 解决: 28
[ 提交][ 状态][ 讨论版]
题目描述
KK和学妹一起去上线性代数课,号称“数学小王子”的KK,听数学课就犯困,为了使KK不睡觉,学妹决定给KK玩一个游戏,来激发KK。
游戏是这样的:给出一个N*N的矩阵,矩阵中分别填入1--N*N个数字,不允许重复,使得矩阵中每行、每列以及每条对角线上的数字之和,全部相等。
为了降低难度,学妹告诉KK,每组测试数据的第一行的正中间的数字一定为1。数据保证N为奇数。
输入
给定一个整数t(0<t<1000),表示有t组测试数据。
每组测试数据有一个奇数N(0<N<200),表示填上N*N个数字。
输出
每组测试数据输出一个N*N的矩阵,每个数字占8位,右对齐,具体格式见输出样例。
样例输入
2 3 5
样例输出
8 1 6 3 5 7 4 9 2 17 24 1 8 15 23 5 7 14 16 4 6 13 20 22 10 12 19 21 3 11 18 25 2 9
提示
来源
思路:
首先第一行正中间的那个数为1,然后通过循环,将当前的那个数的右上方的那个数填为++t,一直这样循环,但是发现有的数没有右上方的数,所以,要将没有的数转化为它的左下脚的数(也就是i=(i%c+c)%c,j=(j%c+c)%c),通过这个转化,就将没有右上角的数转化为左上角的数了,但是也有可能你的右上角的那个数已经被填过了,所以你将下一个数填到当前这个数的下面,还有一种可能,就是当前那个数是最右上角的那个数,它通过上面的转化,也是只能转换为最左下角的那个数,但是那个数肯定是填过了,所以直接将下一个数填到这个数的下面(i=2,j=n的位置)!
有一个口诀:
奇幻七绝
先填上行正中央,
依次斜填切莫忘。
上格没有顶格填,
顶格没有底格放。
代码:
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
int a[205][205];
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
memset(a,0,sizeof(a));
int n;
scanf("%d",&n);
a[1][n/2+1]=1;
int i=1,j=n/2+1,c=n+1;
int t=1;
while(t<n*n)
{
if(i==1&&j==n)
{
i=i+1;
a[i][j]=++t;
}
else
{
int u,v;
u=i-1,v=j+1;
if(u==0)
u=n;
if(v>n)
v-=n;
if(a[u][v]==0)
{
a[u][v]=++t;
i=u,j=v;
}
else
{
i=i+1;
if(i>n)
i-=n;
a[i][j]=++t;
}
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
printf("%8d",a[i][j]);
}
printf("\n");
}
}
return 0;
}
代码2:
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
int a[205][205];
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
memset(a,0,sizeof(a));
int n;
scanf("%d",&n);
int i=0,j=(n/2),t=1;
a[i][j]=1;
while(t<n*n)
{
if(i==0&&j==n-1)
{
a[++i][j]=++t;
}
else
{
int u=((i-1)%n+n)%n,v=((j+1)%n+n)%n;
if(a[u][v]==0)//斜向上填
{
a[u][v]=++t;
i=u,j=v;
}
else//如果填过的话,就在下面填
{
i=(i%n+1)%n;
a[i][j]=++t;
}
}
}
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
printf("%8d",a[i][j]);
}<pre name="code" class="cpp">
代码3(最简单):
因为只要是它循环一圈,它就要在那个下面填下一个数,其他的情况都是直接在它的右上角填上数(这个右上角说的比较宽泛,也就是如果它的右上角的坐标不在n*n的范围内,那么就对n取余,来然他拐回!)
</pre></p><p><pre name="code" class="cpp">#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
int a[205][205];
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n;
scanf("%d",&n);
int i=0,j=n/2,t=1;
while(t<=n*n)
{
int u=(i%n+n)%n,v=(j%n+n)%n;
a[u][v]=t;
if(t%n==0)
{
i++;
}
else
{
i--;
j++;
}
t++;
}
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
printf("%8d",a[i][j]);
}
printf("\n");
}
}
return 0;
}