ZJUT1005做幻方

Description:

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

Input:

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

Output:

输入一个奇数,输出一个幻方,每个数占3格,顺序参照样板输出,输出完以后加一个回车。

Sample Input:

5
1
0

Sample Output:

 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

思路:

1.行向上移N-1个,列向右移一个;

2.如果行小于0,则行上移N-1格后,再下移N格,表现为行下移一格。 如果列大于N,列变为0,即是左边第一个。

3.如果要填的格子有东西了,则原来的列不动,行上移一格。(因此要保存做第二步之前的行列的值)

#include <iostream>
#include <iomanip>
using namespace std;

int main()
{
   for(int N;cin>>N;){
    if(N==0) break;
    int i,j;
    int r=0,l=0;
    int a[30][30];
    for(i=0;i<30;i++)
    for(j=0;j<30;j++){
        a[i][j]=0;
    }
    a[N-1][(N-1)/2]=1;
    i=N-1,j=(N-1)/2;
    for(int c=2;c<=N*N;c++){
        r=i,l=j;               //保存行列的值,
        i-N+1<0? i++:i=i-N+1;  //行向上移N-1个,如果行小于0,则行上移N-1格后,再下移N格,表现为行下移一格。
        j+1>N-1? j=0:j++;      //列向右移一个,如果列大于N,列变为0,即是左边第一个。
        if(a[i][j]!=0){
            a[r-1][l]=c;
            i=r-1,j=l;
        }
        else{
            a[i][j]=c;
        }
    }
    for(i=0;i<N;i++){
      for(j=0;j<N;j++){
      cout<<setw(3)<<a[i][j];
      }
      cout<<endl;
      }
      cout<<endl;
   }
}


你可能感兴趣的:(ZJUT1005做幻方)