主题:十阶幻方问题
lhc,lll
[专家分:0] 发布于 2010-05-27 22:20:00
十行十列,每行每列相加都为505,对角线相加也为505。数字从1到100,如何用c语言编程出来。
回复列表 (共10个回复)
沙发
ciacada [专家分:10] 发布于 2010-05-27 22:43:00
是每个数字只能使用一次还是??
板凳
雪光风剑 [专家分:27190] 发布于 2010-05-27 22:55:00
穷举,并且检查
3 楼
bruceteen [专家分:42660] 发布于 2010-05-27 23:31:00
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
const unsigned N = 10;
unsigned temp[N][N] = { 0 };
unsigned x=N/2, y=N-1;
for( unsigned i=1; i<=N*N; ++i, x=(x+1)%N, y=(y+1)%N )
{
if( temp[y][x] != 0 )
{
x = (x+N-1)%N;
y = (y+N-2)%N;
}
temp[y][x] = i;
}
for( unsigned a=0; a<N; ++a )
{
for( unsigned b=0; b<N; ++b )
cout << ' ' << setw(2) << setfill('0') << temp[a][b];
cout << '\n';
}
cout << endl;
return 0;
}
随手写的,没检查过。
只是用 const unsigned N = 3 验证了一下
4 楼
lhc,lll [专家分:0] 发布于 2010-05-29 15:30:00
三楼写的不太正确,十阶幻方,十行十列,每行十个数字相加为505 ,每列十个数字相加也为505,对角线十个数字相加也为505,1到100数字不能重复。应该用二维数组写吧,分三个步骤,先每行相加为505,再每列相加为505,再对角线。我写了一个半小时也没写出个什么东西。另外在没有每行每列相加等一特定数字时,三阶幻方应该只有一种形式,四阶五阶都多了,到六阶时好像都有上千种,只要每行每列相加后的结果相等。希望大家想想该如何去写。谢谢
5 楼
bruceteen [专家分:42660] 发布于 2010-05-30 18:09:00
http://zh.wikipedia.org/zh/%E5%B9%BB%E6%96%B9
6 楼
雪光风剑 [专家分:27190] 发布于 2010-05-31 07:30:00
[quote]
三楼写的不太正确,十阶幻方,十行十列,每行十个数字相加为505 ,每列十个数字相加也为505,对角线十个数字相加也为505,1到100数字不能重复。应该用二维数组写吧,分三个步骤,先每行相加为505,再每列相加为505,再对角线。我写了一个半小时也没写出个什么东西。另外在没有每行每列相加等一特定数字时,三阶幻方应该只有一种形式,四阶五阶都多了,到六阶时好像都有上千种,只要每行每列相加后的结果相等。希望大家想想该如何去写。谢谢
[/quote]
三阶幻方只有一种形式?我笑了,构造奇数阶幻方的方法知道吧……如果您知道的话,就不可能说出“在没有每行每列相加等一特定数字时,3阶幻方只有一种形式”了。另外……我想知道,您到底是老师还是还是学生,最后一句话的语气就好像老师在引导大家思考,但是您发帖的意图似乎是“我们替您思考”
7 楼
lhc,lll [专家分:0] 发布于 2010-06-01 10:33:00
我是学生,偶尔间看到这道问题,很感兴趣。按我的理解是,从这个十阶幻方所提到的条件来看它还并非是真正幻方。答案是有的,只不过是想用程序编出来,对于有规律性有逻辑性的东西,应该都可以编出,希望感兴趣的同学试一下。
8 楼
lhc,lll [专家分:0] 发布于 2010-06-01 10:46:00
很感谢,只不过我还没有学到java。现在正在学汇编与c++,对于面向对象多态构建之类的东西不了解。等以后了解深了在探讨请教。谢谢大家
9 楼
bruceteen [专家分:42660] 发布于 2010-06-01 15:48:00
只不过我还没有学到java
--- 跟java没关系,我只叫你看文字描述的构造方法(规律),没让你去看什么代码。
10 楼
z9895512 [专家分:0] 发布于 2010-06-04 21:41:00
这是之前学到数组时编写的,可以输出任意阶的幻方,把要求的阶数赋值给n变量就可以。
由于知识有限,有些地方还是不够好~
#include <stdio.h>
void main()
{
int i,j,n=10,m,a[100][100],x,y,z,w;
int b[100][100],at[100][100],c[100][100];
if(n%2==1)//条件成立则执行奇阶幻方,不成立则执行偶阶幻方
{//奇幻方
for(m=1,i=0,j=n/2;m<n*n+1;i--,j++,m++)
{
if(i+1==0&&j-1==n-1)
i=i+2,j=j-1;
if(i==-1)
i=n-1;
if(j==n)
j=0;
if(a[i][j]<0)
a[i][j]=m;
else
i=i+2,j=j-1;
a[i][j]=m;
}
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
printf("%d ",a[i][j]);
}
printf("\n");
}
}
else
{//偶幻方
for(i=0,j=0,m=1;i<n;i++,j++,m++)
a[i][j]=m,a[n-i-1][j]=m;
a[1][0]=n,a[1][n-1]=1;
for(i=0;i<n/2;i++)
{
for(m=1,j=0;j<n;j++,m++)
{
if(a[i][j]<0)
{
if(i==0)
a[i][j]=n-m+1;
else
a[i][j]=m;
}
if(a[i+n/2][j]<0)
{
a[i+n/2][j]=n-m+1;
}
}
}
for(i=0;i<n;i++)
for(j=0;j<n;j++)
b[i][j]=n*(a[i][j]-1),
at[i][j]=a[j][i],
c[i][j]=at[i][j]+b[i][j];
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
printf("%d ",c[i][j]);
}
printf("\n");
}
for(i=0,z=0,w=0;i<n;i++)
{z=c[i][i]+z;//左对角线元素和
w=c[n-i-1][n-i-1]+w;//右对角线元素和
for(j=0,x=0,y=0;j<n;j++)
{
x=c[i][j]+x;//每行元素和
y=c[j][i]+y;//每列元素和
}
printf("%d %d\n",x,y);
}
printf("%d %d\n",z,w);
}
}
我来回复