题目:做幻方

论坛 期权论坛 脚本     
匿名技术用户   2020-12-23 17:25   22   0

题目描述

Apple最近迷上了做幻方,Apple还是个中高手,只要你说个奇数N就能把N*N的幻方做出来。其实你可以比他做得更好的。Apple总是画得很乱,而你可以利用程序排得很整齐^_^ 幻方的要求:每一行,每一列,还有两条斜线上数字的和都相等.

输入

每行一个奇数N(0< N < 30),输入0结束

输出

输入一个奇数,输出一个幻方,顺序参照样板输出;同一列的数右对齐,数与数用一个空格分开;输出完以后加一个回车。

样例输入

5
1
0

样例输出

11 18 25  2  9
10 12 19 21  3
 4  6 13 20 22
23  5  7 14 16
17 24  1  8 15

1

解题思路

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

以上面这个5*5的幻方为例,先把1放置在第一行的最中间,然后接着2放在1的右上方,放置过程中会遇到的问题:

1) 如果超出上界,以上表1与2为例,将把2放置在最底层,也就是 i = i + n;

2) 如果超出右界,以上表3与4为例,将把4放置在最左层,也就是 j = j - n;

3) 如果既超出上界又超出右届,以上表16与17为例,执行1)、2)操作即可;

4) 如果碰到移动位置有数字存在,则按原位置向下走即可,如15和16。

对这个题目ac还有一点就是格式问题,输出是要求数据从后往前输出的,以及要求数字右对齐,如果忽略,很可能会错误。

以下是代码,以c为例:

#include<stdio.h>
int main()
{
 int s[30][30] = { 0 };
 int n, i = 1, j, k;
 int j2, k2;
 while (scanf("%d", &n) != EOF) {
  if (n == 0)
   break;
  for (int i = 0; i < n; i++)
   for (int j = 0; j < n; j++)
    s[i][j] = 0;
  i = 1;
  j = 0; k = (n - 1) / 2;
  s[j][k] = i++;//先放第一个数
  while (i <= n * n)
  {
   j = j - 1;
   k = k + 1;
   while (1) {
    if (j >= 0 && k < n) { //不越界
     if (s[j][k] != 0) { //该位置有数字
      j = j2 + 1;
      k = k2;
      if (j == n) {
       j = j - n;
      }
      continue;
     }
     else
      break;
    }
    else if (j < 0 && k < n) //j越界
     j = j + n; //换到底部
    else if (j >= 0 && k >= n) //k越界
     k = k - n;
    else if (j < 0 && k >= n)//j、k同时越界
    {
     j = j + n;
     k = k - n;
    }
   }
   s[j][k] = i;
   //记录上一次的下标
   j2 = j;
   k2 = k;
   i++;
  }
  int c;
  if (n*n < 10)
   c = 1;
  else if (n*n < 100)
   c = 2;
  else if (n*n < 1000)
   c = 3;
  for (i = n - 1; i >= 0; i--)
  {
   int j; 
   printf("%*d", c, s[i][0]);
   for (j = 1; j < n; j++)
    printf(" %*d", c, s[i][j]);
   printf("\n");
  }
  printf("\n");
 }
 return 0;
}

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:7942463
帖子:1588486
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP