读书人

(填数游戏)计算机傻瓜式计算-求最优

发布时间: 2012-05-23 13:44:13 作者: rapoo

(填数游戏)计算机傻瓜式计算--求最优算法
今天偶然翻看自己以前写的些CODE,发现些有趣的事,这个是在以前亲戚小孩的数学书上发现的题目,感兴趣,就用CODE实现了下,虽然可以算出来,但感觉用的方法不够简单(用了N多层循环呀),想找些更简单的方法--,纯属娱乐。示例代码如下,看到的都提提意见吧,呵呵:

{{0,0,7,4,0,0,0,6,0},
{2,4,0,1,0,0,5,3,0},
{8,0,0,6,0,7,0,0,4},
{1,0,5,0,4,0,0,7,0},
{0,0,9,0,7,0,1,0,0},
{0,7,0,8,0,9,4,0,5},
{9,0,0,3,0,1,0,0,8},
{0,3,8,0,0,4,0,1,2},
{0,1,0,0,0,2,3,0,0}}
注:示例数组,9X9的一个表格,0代表空位,需要在里面填入数字

C/C++ code
/*实现一个9x9的方阵中填入数字,某些空格里面已经填写好了的,补充没有填写的空格。使其行和列都不重复1-9这9个数字,并且每一行和每一列都必须要有1-9这九个数,其中方格中已经填写好的数可以改变,保证同样可以正确的算出*/#include <stdio.h>int compare(int num_arry[9][9], int num, int row, int line){  int i,k=0;  for(i=0; i<9; i++)  {    if(num==num_arry[row][i])       /* the row compare */      k++;    if(num==num_arry[i][line])      /* the line compare */      k++;  }  if(k==0)    return 1;  else    return 0;}test(int num_arry[9][9]){  int tem_arry[9][9];  int num, row, line;  int test=0, no_row=0, no_line=0;  for(row=0; row<9; row++)    for(line=0; line<9; line++)      tem_arry[row][line]=num_arry[row][line];  for(row=0; row<9; row++)    for(line=0; line<9; line++)    {      if(num_arry[row][line]==0)      {        for(num=1; num<10; num++)        {          if(num <= test && row == no_row && line == no_line)            continue;          if(compare(num_arry, num, row, line))          {            num_arry[row][line]=num;            break;          }        }        if(num_arry[row][line] == 0)        {          for(;;)          {            if(line != 0)              line-=1;            else            {              row-=1;              line=8;            }            if(tem_arry[row][line] == 0)     /* compare the number is full in */              break;           }          test = num_arry[row][line];          no_row = row;          no_line = line;          num_arry[row][line] = 0;          if(line != 0) /* the "for" plus the row and line have erro,must sub */            line-=1;          else          {            row-=1;            line=8;          }        }      }    }}int main(){  int num_arry[9][9]={    {0,0,7,4,0,0,0,6,0},    {2,4,0,1,0,0,5,3,0},    {8,0,0,6,0,7,0,0,4},    {1,0,5,0,4,0,0,7,0},    {0,0,9,0,7,0,1,0,0},    {0,7,0,8,0,9,4,0,5},    {9,0,0,3,0,1,0,0,8},    {0,3,8,0,0,4,0,1,2},    {0,1,0,0,0,2,3,0,0}};  int row,line;  for(row=0; row<9; row++)  {    for(line=0; line<9; line++)      printf("%-4d", num_arry[row][line]);    putchar('\n');  }  printf("\n\n");  test(num_arry);  for(row=0; row<9; row++)  {    for(line=0; line<9; line++)      printf("%-4d", num_arry[row][line]);    putchar('\n');  }  return 0;}


[解决办法]
找到了,蛮搞笑的。写的时候没有多想什么,纯粹的懒人直线思维。别看着多,复制粘贴起来很快就写完了。
C/C++ code
/*1-9十个数字,纵横斜相加都为16的的排法*/#include <stdio.h>#define NUM 16void equal(int a[3][3]){    int i,j;    if(a[0][0]+a[0][1]+a[0][2]==NUM)        if(a[1][0]+a[1][1]+a[1][2]==NUM)            if(a[2][0]+a[2][1]+a[2][2]==NUM)                if(a[0][0]+a[1][0]+a[2][0]==NUM)                    if(a[0][1]+a[1][1]+a[2][1]==NUM)                        if(a[0][2]+a[1][2]+a[2][2]==NUM)                            if(a[0][0]+a[1][1]+a[2][2]==NUM)                                if(a[0][2]+a[1][1]+a[2][0]==NUM)                                {                                    for(i=0;i<3;i++)                                    {                                        for(j=0;j<3;j++)                                            printf("%d ",a[i][j]);                                        printf("\n");                                    }                                    printf("\n");                                }    }void main(){    int a[3][3];    int a1,a2,a3,a4,a5,a6,a7,a8,a9;    for(a1=0;a1<10;a1++)        for(a2=0;a2<10;a2++)            for(a3=0;a3<10;a3++)                for(a4=0;a4<10;a4++)                    for(a5=0;a5<10;a5++)                        for(a6=0;a6<10;a6++)                            for(a7=0;a7<10;a7++)                                for(a8=0;a8<10;a8++)                                    for(a9=0;a9<10;a9++)                                    {                                        a[0][0]=a1;                                        a[0][1]=a2;                                        a[0][2]=a3;                                        a[1][0]=a4;                                        a[1][1]=a5;                                        a[1][2]=a6;                                        a[2][0]=a7;                                        a[2][1]=a8;                                        a[2][2]=a9;                                        equal(a);                                    }} 


[解决办法]
应该记录每个各自能取到的数字的记录,能提高效率。
关键是还要记录每个格子能取值的可能数,然后从可能数最少的格子开始尝试,应该能大大提高效率。

探讨
直接上搜索再加上对每个格子能取到的数字的记录 如果存在一个未填的格子什么数都不能填了的话就退出
这样的效率应该比较高

[解决办法]
应该记录每个各自能取到的数字的记录,能提高效率。
关键是还要记录每个格子能取值的可能数,然后从可能数最少的格子开始尝试,每次尝试会导致同行、同列的格子的取值可能数各减一,再次寻找可能数最少的各自开始下一步尝试,直到有一个格子的取值可能数为0。
应该能大大提高效率。


引用:
直接上搜索再加上对每个格子能取到的数字的记录 如果存在一个未填的格子什么数都不能填了的话就退出
这样的效率应该比较高
[/Quote]

读书人网 >软件架构设计

热点推荐