。 。 。
。 。 。 。
。 。 。 。 。
。 。 。 。
。 。 。
如上图,共有十九个位置,填入1 - 19, 使之满足:所有横的和相等, 左斜的和相等,右斜的和相等,
I'm waiting...
Thank U very MUCH
----------------解决方案--------------------------------------------------------
回朔搜索应该可以做,但也是很麻烦.
主要难在剪枝.我想这个题目应该和魔方的一样一定有规律的.
做1-19的全排列(估计运行时间会很长),然后排除.
LZ能不能给出个答案来.看有有没有什么规律,觉得应该不是用回朔,太麻烦了.
----------------解决方案--------------------------------------------------------
正在找规律了 ~~~~~~~~~~`好难 可能不行!!!!!!!!!呵呵 不行不要怪我~
----------------解决方案--------------------------------------------------------
哪位高手帮忙啊
----------------解决方案--------------------------------------------------------
高深...
和魔方有点相似..
但难度还有大些哟....
想想~``
----------------解决方案--------------------------------------------------------
感觉有点不好弄 好好想一哈看看
----------------解决方案--------------------------------------------------------
唉 想不出来 想拉半天 感觉用我的方法有复杂 时间复杂度也大
只知道横斜加起来得38
----------------解决方案--------------------------------------------------------
是否可以将这个六边形转动起来,顺时针或者逆时针转3次,每次检验横行就ok了(每次可以删选数据)......我非专业,不知拙见是否可行。
1总体检验横行。
2数据转动3次。
3每次删选减小运算。
----------------解决方案--------------------------------------------------------
不管你怎么转 只要你最后满足横斜都相等就行
----------------解决方案--------------------------------------------------------
修复了一点错误,头一次没考虑最后一行是多个数时中间的斜行没有判断 正解是:
3 17 18
19 7 1 11
16 2 5 6 9
12 4 8 14
10 13 15
#include "stdio.h"
#define HE 38
int k[19]={0}, s[5][9]={0}; //k[]代表1-19有没有被占用
int test(int a) //从第三行开始就要检查斜行是否符合38
{
int i, j, sum1=0, sum2=0, sum3=0, ia, ja, hs;
hs = a;
for(i=a-2, j=10-a; a > -1; a--) //(a-2)此题中2是中间一行 (10-a)最右边数的位置
{
sum1 += s[a][i++];
sum2 += s[a][j--];
}
if(hs == 4) //到最后一行且最后一行包含2个以上的数字
{
i = hs;
for(i = hs; i<(10-hs); i += 2)
{
sum2 = 0;
sum3 = 0;
ja = ia = i;
for(a = hs; a > -1; a--)
{
sum2 += s[a][ia++];
sum3 += s[a][ja--];
}
if(sum2 != HE || sum3 != HE)
{
sum2 = 0;
break;
}
}
}
if(sum1 == HE)
{
if(sum2 == HE)
return 1; //是1表示成功
else
return 2; //返回2表示左斜边是38
}
else
return 0; //0表示不成功
}
int js(int a, int b, int sum) //a行坐标 b列坐标 sun表示进入此前的行各数之和
{
int i = 0, n, m = 0; //
while(m != 1) //m表示本次找的数不行再找另一个
{
while(k[i] == 1) //找到没被用过的数字
{
if(i > 17)
return 0;
else
i++;
}
n = i + sum + 1;
if(n > HE)
return 0; //返回0表示此行组的数不符合
else
{
k[i] = 1; //如果找到的数符合就做上标记表示被用
s[a][b] = i + 1;
}
if(a==0 || a==4) //
{
if(b < 6)
{
if(b==4 && n>18)
m = js(a, b+2, n);
else if(b==2 && n>2)
m = js(a, b+2, n);
}
else
{
if(a == 0)
{
if(n == HE)
{
m = js(a+1, 1, 0);
}
}
else
{
if(n == HE)
{
m = test(4); //最终检查
}
}
}
}
else if(a==1 || a==3)
{
if(b < 7)
{
if(a == 3 && b == 1) //判断左斜边是否38
{
if(test(3)==2)
m = js(a, b+2, n);
}
else
m = js(a, b+2, n);
}
else
{
if(a == 1)
{
if(n == HE)
m = js(a+1, 0, 0);
}
else
{
if(n == HE)
{
if(test(3) == 1)
m = js(a+1, 2, 0);
}
}
}
}
else //当到中间一行,第三行,a=2 b=0
{
if(b < 8)
{
if(0 == b) //判断左斜边是否38
{
if(test(2) == 2)
m = js(2, 2, 0);
}
else
{
m = js(2, b+2, n);
}
}
else
{
if(n = HE)
if(test(2) == 1)
m = js(3, 1, 0);
}
}
if(m != 1) //函数返回0表示下一个数没找到,此数需要重新找
{
k[i] = 0;
if(i < 18)
{
i++;
}
else
return 0;
}
}
return m;
}
int main()
{
int i, j, n, m, temp;
temp = js(0, 2, 0);
if(temp == 1)
printf("ok\n");
else
printf("flase\n");
for(i=0; i<5; i++)
{
if((i==0 || i==4))
{
j = 2;
m = 7;
printf(" ");
}
else if((i==1 || i==3))
{
j = 1;
m = 8;
printf(" ");
}
else
{
j = 0;
m = 9;
}
for(n=j; n<m; n+=2)
{
if(s[i][n] > 9)
printf("%d ", s[i][n]);
else
printf(" %d ", s[i][n]);
}
printf("\n");
}
return 0;
}
[此贴子已经被作者于2007-5-8 1:48:30编辑过]
----------------解决方案--------------------------------------------------------