当前位置: 代码迷 >> C语言 >> 十九格填数问题
  详细解决方案

十九格填数问题

热度:217   发布时间:2007-05-08 00:11:28.0
晚安
----------------解决方案--------------------------------------------------------

修复了一点错误 :
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=a;
for(i=a-2, j=10-a; a > -1 && s[a][i]; a--) //(a-2)此题中2是中间一行 (10-a)最右边数的位置
{
sum1 += s[a][i++];
sum2 += s[a][j--];
}
if((hs==4) && (sum2==HE) && (sum1==HE)) //到最后一行且最后一行包含2个以上的数字
{
i = hs - 2;
j = 10 - hs;
sum2 = 0;
for(a = hs; i > -1; a--) //即到中间一行 此循环计算- - 这两边的和
{ // - -
sum2 += s[a][i--]; // - -
sum3 += s[a][j++];//
}
if((sum2 != HE) || (sum3 != HE))
sum2 = 0;
else
for(i = hs; i < (10-hs); i += 2)
{
sum2 = 0;
sum3 = 0;
ja = ia = i;
for(a = hs; s[a][ia]>0 || s[a][ja]>0; a--)
{
if(s[a][ia] > 0)
sum2 += s[a][ia++];
if(s[a][ja] > 0)
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-9 3:42:02编辑过]


----------------解决方案--------------------------------------------------------
大侠~好崇拜啊~~~~
----------------解决方案--------------------------------------------------------
回复:(iwfy)修复了一点错误,头一次没考虑最后一行...

你真的太厉害了,谢谢,谢谢
向你学习


----------------解决方案--------------------------------------------------------
22楼比上面的能完善些

我写的太长了,能力有限,代码没优化
----------------解决方案--------------------------------------------------------
如果不使用#define N 38怎么设计,谢谢
----------------解决方案--------------------------------------------------------
回复:(yihai0494)十九格填数问题

对了,这个问题叫六角幻方问题。彼时不知道,不好意思哦。


----------------解决方案--------------------------------------------------------

外面12个数很好找得 也很容易排列出来 


----------------解决方案--------------------------------------------------------

真是厉害啊!敬佩...你的毅力


----------------解决方案--------------------------------------------------------
佩服写代码的勇气
----------------解决方案--------------------------------------------------------
  相关解决方案