粗略地用C++写了个,因为用C个人感觉实在太麻烦:
#include <iostream>
#include <valarray>
#include <algorithm>
#include <cstddef>
#include <deque>
#include <cmath>
#include <iomanip>
using namespace std;
// 打印函数
template<class T>
void print(valarray<T>& t);
// 判定函数
template<class T>
bool judge(valarray<T>& data);
int main()
{
// 这里表示数字从1~9的魔方,一般写1,4,9,16...才能构成正方形
const size_t N = 9;
deque<size_t> data;
for(size_t i = 1; i <= N; ++i)
{
data.push_back(i);
}
valarray<size_t> valdata(data.size());
size_t count = 0;
while(next_permutation(data.begin(), data.end()))
{
for(size_t i = 0; i < valdata.size(); ++i)
valdata[i] = data[i];
if(judge(valdata))
{
++count;
cout << "魔方" << count << " : " << endl;
print(valdata);
}
}
}
template<class T>
void print(valarray<T>& t)
{
const size_t length = sqrt(static_cast<double>(t.size()));
for(size_t i = 0; i < t.size(); ++i)
{
if(i%length == 0)
cout << endl;
cout << setw(3) << t[i];
}
cout << endl;
}
template<class T>
bool judge(valarray<T>& data)
{
valarray<size_t> test(data), plus_unit;
// 魔方边长
const size_t length = sqrt((double)data.size());
// 加和单位,包括横、纵、斜
plus_unit = test[slice(0,length,1)];
// 每个加和单位的总和
const size_t unit_sum = plus_unit.sum();
// 横排检验
for(size_t row = 0; row < length; ++row)
{
plus_unit = test[slice(row*length,length,1)];
if(plus_unit.sum() != unit_sum)
{
return false;
}
}
// 竖排检验
for(size_t col = 0; col < length; ++col)
{
plus_unit = test[slice(col,length,length)];
if(plus_unit.sum() != unit_sum)
{
return false;
}
}
// 对角线1
plus_unit = test[slice(0,length,length+1)];
if(plus_unit.sum() != unit_sum)
{
return false;
}
// 对角线2
plus_unit = test[slice(length-1,length,length-1)];
if(plus_unit.sum() != unit_sum)
{
return false;
}
return true;
}
以下是3×3的正方形的测试结果:
魔方1 :
2 7 6
9 5 1
4 3 8
魔方2 :
2 9 4
7 5 3
6 1 8
魔方3 :
4 3 8
9 5 1
2 7 6
魔方4 :
4 9 2
3 5 7
8 1 6
魔方5 :
6 1 8
7 5 3
2 9 4
魔方6 :
6 7 2
1 5 9
8 3 4
魔方7 :
8 1 6
3 5 7
4 9 2
魔方8 :
8 3 4
1 5 9
6 7 2
请按任意键继续. . .
告戒一句,不要想去找出大于边为3的正方形的其他魔方(比如:16,25,36...),比如3×3的正方形由1~9这9个数成,所以由1到9组成的不同排列就有:
9! = 362880种;
而4×4的正方形由数字1~16组成却有惊人的:
16! = 20922789888000种!
所以你如果试图把const size_t N = 9;改为const size_t N = 16;的话,估计你可能要开着机器算几个月(排除你有超级电脑的例外)。
我设计的这种算法太劣,4楼的那个叶子里的其实才是最理想的效果......
温馨提示:内容为网友见解,仅供参考
C语言的问题!
5,最后一步是,当程序以混合语言编写的程序链接时,在FORTRAN库之前指定C库。重新解决了秋天的飞行问题。
c语言符号问题这里的!()是什么意思
!是单目运算符,即逻辑运算中的 非。括号内(i%a)是取余运算,然后对运算结果取非。C语言中,一般默认运算结果为0是 是逻辑假,运算结果为非0时,是逻辑真,在这里,若i%a的取余结果为0,即逻辑假,那么!(i%a)即为逻辑真,然后执行if(){}内的语句。
c语言排列组合问题
只要C的上面是0,不管下面是什么都等于1。分子是从5开始递减的两个数字相乘,即5*4;分母为从1开始递增的两个数字,即1*2;所以结果为5*4÷(1*2)=10;同理:c53=5*4*3÷(1*2*3)=10 c54=5*4*3*2÷(1*2*3*4)=5 从n个不同元素中,任取m(m≤n,m与n均为自然数,下同)个...
求助C语言中关于“!”的问题
n!是求N的阶乘。就是1*2*3*4...*N“!”就两个意思,一个是非的意思,一个是阶乘的意思,不知你说的是哪个?全句是什么,我没有那本书。
C语言题目!!
C选项:char ch[3]="abc";\/\/这是字符串赋值语句,在B中也说了,字符串必须0结尾,但是空间只有3,放入了abc再放不下0了,空间不够,编译就不会通过,所以错了,char ch[4]="abc";就没问题。D选项:char ch[4];ch="abc";\/\/ch空间够了,但是这是2条语句,char ch[4];已经开辟了空间,...
求c语言一些常见问题,
在许多高级语言中,用“=”符号作为关系运算符“等于”。如在BASIC程序中可以写 if (a=3) then …但C语言中,“=”是赋值运算符,“==”是关系运算符。如:if (a==3) a=b;前者是进行比较,a是否和3相等,后者表示如果a和3相等,把b值赋给a。由于习惯问题,初学者往往会犯这样的错误。5....
C语言问题!!!
4、x<y?y:x++的计算方式为,先判断x<y是否为真,如果真,则整个表达式的值为y,否则为x++。在这个问题中,由于x<y为假,所以整个表达式的值为x++,所以结果为5,道理和上个题目一样。(如果把它改成x<y?y:++x的话,则结果为6,因为++x是先使x的值增1,然后再将增加后的x的值作为++x...
c语言 !问题
for(;(c=getchar())!='\\n';)少一个左( 号,从键盘上输入一个字符,判断是不是回车!
C语言问题!!!
main(){ int i,j;for(i=0;i<6;i++) \/*控制输出行,共6行*\/ { for(j=0;ji;j--) \/*控制每行的*号数*\/ printf("*");printf("\\n"); \/*每行后换行*\/ } } 2. .#include "stdio.h"main(){ int i,j;for(i=0;i<6;i++) \/*控制输出行,共6行*\/ { for(j...
c语言程序设计问题
答:一个一个来:先看i:i=15; m=(i++)+(i++)+(i++); 可以化解为: m=i+i+i; i++; i++; i++;从左至右执行。这是c语音的执行顺序。得 m=45;在看j:j=20; n=(--j)+(--j)+(--j);可以化解为:看计算机先后执行顺序:先算第一个--j,再算第二个--j,在...