首页 > 试题广场 >

给定一个奇数n,比如n=3,生成1到n平方的数,如1到9,填

[问答题]
给定一个奇数n,比如n=3,生成1到n平方的数,如1到9,填入九宫格,使得横竖斜的和都相等。
推荐
先来个3*3

8 1 6
3 5 7
4 9 2



n奇数幻方口诀:
1. 数字1放在第一行中间
2. 依次放在上一个数的右上角
2.1如果右边出去了就回到左边(3,4)
2.2 如果上面出去了就放下面(1,2)
2.3 如果右上角有了就放在这个数的下面(参考5,6)

5*5
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



发表于 2014-11-10 14:37:21 回复(5)
#include<cstdlib>
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
int n;
cout<<"输入n";
cin>>n;
int *array=new int[n*n];//定义一维数组 
for(int m=0;m<n*n;m++)
{
 array[m]=0;
}//将数组 全部置为0 如果使用memset  当n=5时 array[1] 并没有赋值为0 不知道为什么. 
int i,j,k; 
i=0;
j=n/2;
array[j]=1;
for(k=2;k<n*n+1;k++)
{
       if(j+1<n && i-1>=0)//判断非第一行且右边不越界 
            {
                if( array[(i-1)*n+j+1]==0)//如果右上角有就写入K 
                {
                    i--;
                    j++;
                }
                else//右上角没有 写入下一行 
                {
                    i++;
                }
            }
            else if(j+1>=n && i-1<0)//右边越界且是第一行 
            {
            if(array[(n-1)*n]==0)
{
j=0;
i=(n-1)*n;

               else
  {
  i++;
  } 
            }
            else if(j+1>=n)//只是右边越界 
            {
            if(array[(i-1)*n]==0)
                {
                j=0;
                i--;}
                else i--;
            }
            else //第一行的时候 
            {
            //cout<<array[(n-1)*n+j+1]<<endl;
              if(array[(n-1)*n+j+1]==0)
               {
               i=n-1;
                j++;
                //cout<<1;
}
                else
                {
                i++;
                }
            }
            array[i*n+j]=k;
}
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
cout<<"  "<<array[i*n+j];
}
cout<<endl;
}

}

发表于 2015-03-29 08:11:24 回复(0)
奇数幻方构造方法:
1)在N*N的第一行中间插入1
2)在插入数据1的的位置的右上方插入数据2,若出边框,即在1的上边框,则2的插入位置是向下移动N个位置
3)在插入数据2的右上方插入数据,若出右边框,则向左移动N个位置,插入3
4)下面的插入数据都是在上一个插入数据的右上角插入,若右上角出了上边框,则向下移动N个位置;若右上角位置出了右边框,则向左移动N个位置;若右上角已经被占,则下一个数的位置是上一个数位置的下面;若右上角是整个N*N的最右边,且被占,则下个插入位置在最右边位置的下面位置。
发表于 2015-08-25 12:07:24 回复(1)
#include <iostream>
#include <vector>
#include <string>
#include <stdlib.h>
#include <stdio.h>
#include <climits>
#include <cmath>
#include <map>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <string.h>
using namespace std;
/*
n奇数幻方口诀:
1. 数字1放在第一行中间
2. 依次放在上一个数的右上角
2.1如果右边出去了就回到左边
2.2 如果上面出去了就放下面
2.3 如果右上角有了就放在这个数的下面
*/
void magic_box(int N){
    vector<vector<int> > box(N,vector<int>(N,0));
    if(N&0x1!=1)return;
    int x=0,y=(N>>1);
    box[x][y]=1;
    int count=1,bound=N*N;
    while(count<bound){
        int nx=(x+N-1)%N;
        int ny=(y+1)%N;
        if(box[nx][ny]!=0){
            nx=(x+1)%N;ny=y;
        }
        box[nx][ny]=++count;
        x=nx;y=ny;
    }
    for(int i=0;i<N;i++){
        for(int j=0;j<N;j++){
            cout<<box[i][j]<<",";
        }
        cout<<endl;
    }
}
int main(){
    cout<<"========================Cut Line=========================="<<endl;
    magic_box(3);
    cout<<"========================Cut Line=========================="<<endl;
    magic_box(5);
    cout<<"========================Cut Line=========================="<<endl;
    magic_box(7);
}

发表于 2015-09-27 23:16:11 回复(0)
刚写完的n阶幻方算法:
package com.zxf.niuke;

import org.junit.Test;
/**
 * 幻方
 * */
public class MagicSquare {
    
    //奇数阶幻方
    /**
     * 算法:1位于第一行中间,后面数字在之前一个数字右上角,若右上角已有数字则在之前数字下方
     * */
    public int[][] oddMagicSquare(int n,int start){
        if(n%2 == 0) {
            return null;
        }
        int[][] result = new int[n][n];
        int row = 0;
        int col = n/2;
        for(int i=start;i<=n*n+start-1;i++) {
            result[row][col] = i;
            int nextrow = (row+n-1)%n;
            int nextcol = (col+1)%n;
            if(result[nextrow][nextcol]!=0) {
                row = (row+1)%n;
            }else {
                row = nextrow;
                col = nextcol;
            }
        }
        return result;
    }
    //双偶数阶幻方n=4k
    /**
     * 算法:先构建一个顺序矩阵,再切割成4*4矩阵,每个矩阵的对角线上数字换成其互补的数
     * */
    public int[][] doubleEvenSquare(int n,int start){
        if(n%4!=0) {
            return null;
        }
        int[][] result = new int[n][n];
        int value = start;
        for(int i=0;i<n;i++) {
            for(int j=0;j<n;j++) {
                result[i][j] = value++;
            }
        }
        //换数
        for(int i=0;i<n;i++) {
            for(int j=i%4;j<n;j+=4) {
                result[i][j] = n*n+2*start-1 - result[i][j];
            }
            for(int k=(n-1-(i%4));k>=0;k-=4) {
                result[i][k] = n*n+2*start-1 - result[i][k];
            }
        }
        return result;
    }
    //单偶数阶幻方 n=4k+2
    /**
     * 算法:将矩阵均分为4个矩阵,假设为四个象限
     * 用奇幻方算法按1/4/2/3象限初始化4个矩阵拼接成大幻方
     * 在第一象限中,标记中心格所在行自中心格(包含中心格)起右侧k格和非中心行的中心格(不包含中心格)左侧k格与第三象限交换
     * 在第二象限中,标记中心列左侧(包含中心列)k-1列与第四象限交换,若k-1=0;则不标记
     * */
    public int[][] singleEvenSquare(int n,int start){
        if(n%4!=2) {
            return null;
        }
        int k = (n-2)/4;//
        int m = n/2;//象限矩阵的阶数
        int[][] result = new int[n][n];
        //创建4个小矩阵
        int[][] A = oddMagicSquare(m, start);
        int[][] B = oddMagicSquare(m, 2*m*m+start);
        int[][] C = oddMagicSquare(m, 3*m*m+start);
        int[][] D = oddMagicSquare(m, m*m+start);
        //初始化大矩阵
        for(int i=0;i<m;i++) {
            for(int x=0;x<m;x++) {
                result[i][x] = A[i][x];
            }
            for(int y=m;y<n;y++) {
                result[i][y] = B[i][y-m];
            }
        }
        for(int j=m;j<n;j++) {
            for(int x=0;x<m;x++) {
                result[j][x] = C[j-m][x];
            }
            for(int y=m;y<n;y++) {
                result[j][y] = D[j-m][y-m];
            }
        }
        //标记并交换数
        int center = m/2;
        for(int i =0;i<m;i++) {
            if(center == i) {
                for(int j=center;j<k+center;j++) {
                    swap(result, i, j, i+m, j);
                }
            }else {
                for(int j=0;j<k;j++) {
                    swap(result, i, j, i+m, j);
                }
            }
            for(int j=center+m;j>center+m-(k-1);j--) {
                swap(result, i, j, i+m, j);
            }
        }
        return result;
    }
    public int[][] createMagicSquare(int n,int start){
        if (n<3) {
            return null;
        }
        if(n%2 == 1) {
            return oddMagicSquare(n, start);
        }else if (n%4 == 0) {
            return doubleEvenSquare(n, start);
        }else {
            return singleEvenSquare(n, start);
        }
    }
    public void swap(int[][] a,int x1,int y1,int x2,int y2) {
        int temp = a[x1][y1];
        a[x1][y1] = a[x2][y2];
        a[x2][y2] = temp;
    }
    //打印幻方
    public void printSquare(int[][] a) {
        if (a==null) {
            System.out.println("不存在");
        }
        int len = a.length;
        for(int i=0;i<len;i++) {
            for(int j=0;j<len;j++) {
                System.out.print(a[i][j]+"  ");
            }
            System.out.println();
        }
    }
    //测试类
    @Test
    public void test() {
        printSquare(createMagicSquare(7,1));
    }
    
} 


发表于 2015-09-17 13:01:17 回复(0)
vector<vector<int> > MagicMatrix(int n){
	vector<vector<int> >result(n, vector<int>(n, 0));
	int count=1;
	int curi=0, curj=n/2;
	int nexti=curi, nextj=curj;
	while (count <= n*n){
		if (result[nexti][nextj] == 0){	//还没有填入数据时,向右上方向更新curi和curj的值
			curi=nexti;
			curj=nextj;
		}
		else                            //如果已经填入数据了,则向下更新curi的值
			curi=curi+1;

		result[curi][curj] = count++;	//注意,curi,curj坐标值保持不变,计算下一个位置坐标nexti和nextj
		nexti = curi - 1;
		nextj = curj + 1;
		if (nexti<0)	nexti = n - 1;	//如果向上越界,则向下移
		if (nextj>n-1)	nextj = 0;	//如果向右越界,则向左移
	}
	return result;
}

发表于 2015-09-10 21:54:41 回复(0)
#include<iostream>
#include<vector>
using namespace std;

/** 生成矩阵虽然顺序不一样,但是同样满足要求*/ //生成矩阵函数
int **createMatrix(const int n){
	int **matrix;
	int num_matrix = n * n;
	matrix = new int*[n];	//动态生成 n*n个元素的二维数组
	for (int i = 0; i < n; i++)
		matrix[i] = new int[n];
	//memset(matrix, 0, sizeof(matrix));

	for (int i = 0; i< n; ++i)
		for (int j = 0; j < n; ++j)
			matrix[i][j] = 0;

	//对数组进行赋值
	int first = 0, second = n / 2;

	for (int i = 1; i < (num_matrix + 1); i++){
		if (matrix[first][second] != 0){			
			first ++;
		}	
		matrix[first][second] = i;
				
		first--;
		second++;
		if (first < 0) first = n - 1;
		if (second > n-1) second = 0;
	}

	return matrix;
}


int main(){
	int n;	

	cout << "Input the odd number..."<<endl;
	cin >> n;
	while (n % 2 != 1){
		cout << "The inputed number is not odd..."<<endl;
		cin >> n;
	}
	cout.setf(std::ios::left);
	int **a = createMatrix(n);
	for (int i = 0; i < n; i++){
		for (int j = 0; j < n; j++){
			cout.width(5);
			cout << a[i][j];
		}
		cout << endl;
	}

	delete[]a;

	return 0;
}

发表于 2017-08-30 00:44:37 回复(0)
#include<iostrem>


发表于 2017-07-22 21:41:27 回复(0)
#include <iostream>

void shudu()
{
	const int n=3;
	int a[n][n]={0};
	int i,j;
	i=0;
	j=n/2;
	a[i][j]=1;
	for(int c=2;c<=n*n;c++)
	{
		if (i-1>=0&&j+1<n)
		{
			if (a[i-1][j+1]==0)
			{
				i=i-1;
				j=j+1;
			}
			else
			{
				i=i+1;
			}
		}
		else
		{
			if (i-1<0&&j+1>=n)
			{
				i=i+1;
			}
			else
			{
				if (j+1>=n)
				{
					i=i-1;
					j=j+1-n;
				}
				else
				{
					j=j+1;
					i=i-1+n;
				}
			}
		}
		a[i][j]=c;
	}

	for (i=0;i<n;i++)
	{
		for (j=0;j<n;j++)
		{
			std::cout<<a[i][j]<<" ";
		}
		std::cout<<std::endl;
	}
}

发表于 2015-07-08 21:26:58 回复(0)

void sudoku()
{
 int array[length][length] = {0};
 int i=0,j = length/2;
 for(int k=1;k<=length*length;k++)
 {
  array[i][j]  = k;
  i--;
  j++;//右上一格

  while(i<0 || j>=length || array[i][j] > 0)
  {
   if(i<0 && j>=length)
   {
    if(array[length -1][0] == 0)
    {
     i = length -1;
     j = 0;
    }
    else
    {
     i++;
    }
   }
   else if(i<0)
   {
    i = length -1;
   }
   else if(j>=length)
   {
    j =0;
   }
   else
   {
    i+=2;
    j--;
   }
  }
 }
}

发表于 2015-04-19 23:38:50 回复(0)
public class OddMagicMatrix {

    public static void main(String[] args) {
        // 输入奇数维n
        System.out.println("输入奇数n:");
        Scanner keyIn = new Scanner(System.in);
        int n = 0;
        while (keyIn.hasNext()) {
            n = keyIn.nextInt();
            // 初始化二维矩阵
            int mat[][] = new int[n][n];
            // 一居首行正***
            int x = 0, y = n / 2;
            mat[x][y] = 1;
            // 依次斜填右上方x-1,y+1
            for (int i = 2; i <= n * n; i++) {
                int newX = x - 1, newY = y + 1;
                // 右出框时向左写
                if (newY > n - 1) {
                    newY = 0;
                }
                // 上出框时往下放
                if (newX < 0) {
                    newX = n - 1;
                }
                // 遇到重合无处填,退居原数正下方
                if (mat[newX][newY] != 0) {
                    newX = x + 1;
                    newY = y;
                }
                // 填入矩阵
                mat[newX][newY] = i;
                x = newX;
                y = newY;
            }
            // 输出结果
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < n; j++) {
                    System.out.print(mat[i][j] + "\t");
                }
                System.out.println();
            }
        }
    }
}

发表于 2015-04-19 11:09:25 回复(0)
采用深度优先算法:
#define N 5
int book[N*N] = {0};
int a[N][N] = {0};
void deepfs(int step){
if(step == N*N){
if(若行列斜相等)
打印数组;
return;
}

for(int i = 0; i < N*N; i++){
if(book[i] == 0){
book[i] = 1;
int m = step / N;
int n = step % N;
a[m][n] = i;

deepfs(step+1);
book[i] = 0;
}
}
return;
}

int main(){
dfs(0);
return 0;
}

发表于 2015-03-29 11:32:44 回复(1)
我是看了@叶小鱼 的思路才知道的。自己完全想不出来。虽然最后写出来了,但在编程的过程中发现,那几句话并不好写判断。特别是【当右上都出界的时候】怎么处理。我这里的处理方式就是把他放在当前数字的下面。

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

int maze[20][20];
int main()
{
    int n;
    while(cin>>n)
    {
        memset(maze,0,sizeof(maze));
        int i,j,k;
        i=1;
        j=n/2+1;
        maze[i][j]=1;
        for(k=2; k<=n*n; k++)
        {
            if(j+1<=n && i-1>=1)
            {
                if( maze[i-1][j+1]==0)
                {
                    i--;
                    j++;
                }
                else
                {
                    i++;
                }
            }
            else if(j+1>n && i-1<=0)
            {
                i++;
            }
            else if(j+1>n)
            {
                j=1;
                i--;
            }
            else
            {

                i=n;
                j++;
            }
            maze[i][j]=k;
        }
        for(i=1; i<=n; i++)
        {
            for(j=1; j<=n; j++)
            {
                cout<<maze[i][j]<<" ";
            }
            cout<<endl;
        }
    }
    return 0;
}

发表于 2015-03-26 15:22:55 回复(1)
#include<cstdlib>
#include<iostream>

using namespace std;

int main()
{
    int n;
    int double_n;
    int *array;
    int count = 1;
    int row_location;
    int column_location;
    int row_temp;
    int column_temp;

    //get n
    do
    {
        cout << "Enter the value of n: " << endl;
        cin >> n;
    } while ((n % 2) != 1);
    double_n = n * n;
    array = new int[double_n];
    for (int i1 = 0; i1 < double_n; i1++)
    {
        array[i1] = 0;
    }

    //fill the table
    column_location = n / 2;
    row_location = 0;
    array[column_location] = 1;
    while (count != double_n)
    {
        count++;
        row_temp = (n + row_location - 1) % n;
        column_temp = (column_location + 1) % n;
        if (array[row_temp * n + column_temp] == 0)
        {
            row_location = row_temp;
            column_location = column_temp;
            array[row_location * n + column_location] = count;
        }
        else
        {
            row_location = (row_location + 1) % n;
            array[row_location * n + column_location] = count;
        }
    }

    //show table
    for (int i1 = 0; i1 < n; i1++)
    {
        for (int i2 = 0; i2 < n; i2++)
        {
            cout << array[i1 * n + i2] << " ";
        }
        cout << endl;
    }

    system("pause");
    return 0;
}
发表于 2015-03-24 18:38:03 回复(0)

发表于 2014-12-25 20:42:11 回复(0)
流头像
没有特别好的想法


bool judge(int n,int g)
{
    int sn=(1+n*n)/2*n;
    for(int i=0;i<n;i++){
        int sc=0,sr=0;
        for(int j=0;j<n;j++){
            sc+=g[i][j];
            sr+=g[j][i]
        }
        if(sc!=sn || sr!=sn) return false;
    }
    int srr=0,scc=0;
    for(int i=0;i<n;i++) {
        srr+=g[i][i];
        scc+=g[i][n-i-1];
    }      
    if(srr!=sn || scc!=sn) return false;
    return true;
}

void print_grid(int n,int **g)
{
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
            printf(j==n-1?"%d\n":"%d ",g[i][j]);
}

bool judge0(int n,int m,int g)
{
    int sn=(1+n*n)/2*n;
    for(int i=0;i<m/n;i++){
        int sc=0;
        for(int j=0;j<n;j++)
            sc+=g[i][j];
        if(sc!=sn) return false;
    }
    return true;
}

void get_grid(int n,int m,int **g,bool jud[])
{
    if(judge0(n,m,g)) return;
    if(m==n*n && judge(n*n,g))
        print_grid(n*n,g);
    for(int i=m;i<n*n;i++)
        for(int j=0;j<n*n;j++){
                if(!jud[i]){
                    judge[i]=1;
                    g[m/n][m%n]=i;
                    get_grid(n,m+1,g,jud);
                    jud[i]=0;
                }
        }
}
发表于 2014-12-19 16:30:52 回复(0)
横竖斜相等?这么有问题的题目我不回答
发表于 2014-12-03 19:14:22 回复(1)
壕头像
XcXcXcXcXZc
发表于 2014-12-01 21:55:46 回复(0)
~
发表于 2014-11-29 06:51:06 回复(0)
#include <stdio.h>

1、先给定一个数n
2、生成1—n的平方数,用一个数组保存
3、九宫格可以看做是个3x3的二位数组
4、分别就横竖斜的值相加然后用三个变量保存
5、比较三个变量的值判断是否相等
 
int main(void)
{
    int n;
    int i;
    int heng, shu, xie;
    
    scanf("%d", &n);
    for(i=1; i<=n; i++)
    {
        arr[i-1] = i * i;
    }
    for(i=0; i<n; i++)
    {
        printf("%d\t", arr[i]);
    }

    return 0;
}
发表于 2014-11-09 15:40:18 回复(1)
111
发表于 2014-11-04 10:33:52 回复(0)