八皇后的C语言实现
来源:互联网 发布:centos 6.5改ssh端口 编辑:程序博客网 时间:2024/05/17 06:24
唯一的一门语言课Java课上老师讲过这个问题,使用“回退”的方法,期末考试也考过,但是这么多年来一直没有亲自去做过它,即使偶尔想到也觉得太过麻烦,没有那个能力实现。但是前两天一个兄弟作出来了,我觉得我也应该作出来,要不然实在没面子,于是使用C语言来实现一下。
一开始,我使用struct(A)来保存每一个皇后的位置,另外使用了一个struct(B)来保存当前列之前所有列中已放过皇后的位置,以防重复处理;我觉得方法思想上是没有问题的,但是运行的时候一个结果都没有出来,进入了死循环。我发现是往B中插入的数据没有成功,虽然在那个小funcion里边是没问题了,出来之后就回到原样了,因此已放过皇后的位置总是没有保存,每次都回退到之前的位置。
后来,我想到了另外一种实现,不使用struct,使用两个数组,分别保存每一列皇后的位置,已经皇后走过的标志(使用了2的row次方的方法,实际上跟前一个数组差不多),然后按照这个思路的结果,前边4个答案出来了,然后死循环,直到stack overflow。当我仔细分析算法的时候,我发现另一种更简洁一点的实现,只用一个数组,因为每一个数组元素储存的就是该列已经尝试过的最大值,下一次应该从它的下一个位置寻找。按照这个思路实现的结果跟上一个一样,只出来了4个答案(还差了88个)。
我再分析,发现是第一列第一个位置的所有可能情况找出来之后没法跳出循环,寻找第一列第二个位置的情况,于是我添加了
if (i>=ROW && column==1)
break; /*45-46行*/
如果第二列已经找到头了,就跳出。这个结果是得到了88个,看来最后一个位置(第一列)还有问题。于是我再添加了
else if (column==0 && i>5)
break; /*47-48行*/
当回退到第一列的时候,第二列如果序号超过了5,就跳出,因为序号6和7是肯定无法匹配的。这样就没有问题了。
但是这样修改我觉得不够清晰明了,难解释,今早我想除了另外一个办法,在之后某个地方添加
if (coulmn == 0)
break; /*73-74行*/
这是回退的时候如果退到第一列了,说明第一列当前位置已经搜索完毕,可以进入下一个位置了,根据实现,这里的循环就应该出来了。
具体的实现参看如下的源代码:
当然,由于没有保存每次的结果的机制,所以每次完成之后都将结果打印出来,按照列的顺序,每一个数字是在列中的编号。
1>>> 0, 4, 7, 5, 2, 6, 1, 3,
2>>> 0, 5, 7, 2, 6, 3, 1, 4,
3>>> 0, 6, 3, 5, 7, 1, 4, 2,
4>>> 0, 6, 4, 7, 1, 3, 5, 2,
5>>> 1, 3, 5, 7, 2, 0, 6, 4,
6>>> 1, 4, 6, 0, 2, 7, 5, 3,
7>>> 1, 4, 6, 3, 0, 7, 5, 2,
8>>> 1, 5, 0, 6, 3, 7, 2, 4,
9>>> 1, 5, 7, 2, 0, 3, 6, 4,
10>>> 1, 6, 2, 5, 7, 4, 0, 3,
11>>> 1, 6, 4, 7, 0, 3, 5, 2,
12>>> 1, 7, 5, 0, 2, 4, 6, 3,
13>>> 2, 0, 6, 4, 7, 1, 3, 5,
14>>> 2, 4, 1, 7, 0, 6, 3, 5,
15>>> 2, 4, 1, 7, 5, 3, 6, 0,
16>>> 2, 4, 6, 0, 3, 1, 7, 5,
17>>> 2, 4, 7, 3, 0, 6, 1, 5,
18>>> 2, 5, 1, 4, 7, 0, 6, 3,
19>>> 2, 5, 1, 6, 0, 3, 7, 4,
20>>> 2, 5, 1, 6, 4, 0, 7, 3,
21>>> 2, 5, 3, 0, 7, 4, 6, 1,
22>>> 2, 5, 3, 1, 7, 4, 6, 0,
23>>> 2, 5, 7, 0, 3, 6, 4, 1,
24>>> 2, 5, 7, 0, 4, 6, 1, 3,
25>>> 2, 5, 7, 1, 3, 0, 6, 4,
26>>> 2, 6, 1, 7, 4, 0, 3, 5,
27>>> 2, 6, 1, 7, 5, 3, 0, 4,
28>>> 2, 7, 3, 6, 0, 5, 1, 4,
29>>> 3, 0, 4, 7, 1, 6, 2, 5,
30>>> 3, 0, 4, 7, 5, 2, 6, 1,
31>>> 3, 1, 4, 7, 5, 0, 2, 6,
32>>> 3, 1, 6, 2, 5, 7, 0, 4,
33>>> 3, 1, 6, 2, 5, 7, 4, 0,
34>>> 3, 1, 6, 4, 0, 7, 5, 2,
35>>> 3, 1, 7, 4, 6, 0, 2, 5,
36>>> 3, 1, 7, 5, 0, 2, 4, 6,
37>>> 3, 5, 0, 4, 1, 7, 2, 6,
38>>> 3, 5, 7, 1, 6, 0, 2, 4,
39>>> 3, 5, 7, 2, 0, 6, 4, 1,
40>>> 3, 6, 0, 7, 4, 1, 5, 2,
41>>> 3, 6, 2, 7, 1, 4, 0, 5,
42>>> 3, 6, 4, 1, 5, 0, 2, 7,
43>>> 3, 6, 4, 2, 0, 5, 7, 1,
44>>> 3, 7, 0, 2, 5, 1, 6, 4,
45>>> 3, 7, 0, 4, 6, 1, 5, 2,
46>>> 3, 7, 4, 2, 0, 6, 1, 5,
47>>> 4, 0, 3, 5, 7, 1, 6, 2,
48>>> 4, 0, 7, 3, 1, 6, 2, 5,
49>>> 4, 0, 7, 5, 2, 6, 1, 3,
50>>> 4, 1, 3, 5, 7, 2, 0, 6,
51>>> 4, 1, 3, 6, 2, 7, 5, 0,
52>>> 4, 1, 5, 0, 6, 3, 7, 2,
53>>> 4, 1, 7, 0, 3, 6, 2, 5,
54>>> 4, 2, 0, 5, 7, 1, 3, 6,
55>>> 4, 2, 0, 6, 1, 7, 5, 3,
56>>> 4, 2, 7, 3, 6, 0, 5, 1,
57>>> 4, 6, 0, 2, 7, 5, 3, 1,
58>>> 4, 6, 0, 3, 1, 7, 5, 2,
59>>> 4, 6, 1, 3, 7, 0, 2, 5,
60>>> 4, 6, 1, 5, 2, 0, 3, 7,
61>>> 4, 6, 1, 5, 2, 0, 7, 3,
62>>> 4, 6, 3, 0, 2, 7, 5, 1,
63>>> 4, 7, 3, 0, 2, 5, 1, 6,
64>>> 4, 7, 3, 0, 6, 1, 5, 2,
65>>> 5, 0, 4, 1, 7, 2, 6, 3,
66>>> 5, 1, 6, 0, 2, 4, 7, 3,
67>>> 5, 1, 6, 0, 3, 7, 4, 2,
68>>> 5, 2, 0, 6, 4, 7, 1, 3,
69>>> 5, 2, 0, 7, 3, 1, 6, 4,
70>>> 5, 2, 0, 7, 4, 1, 3, 6,
71>>> 5, 2, 4, 6, 0, 3, 1, 7,
72>>> 5, 2, 4, 7, 0, 3, 1, 6,
73>>> 5, 2, 6, 1, 3, 7, 0, 4,
74>>> 5, 2, 6, 1, 7, 4, 0, 3,
75>>> 5, 2, 6, 3, 0, 7, 1, 4,
76>>> 5, 3, 0, 4, 7, 1, 6, 2,
77>>> 5, 3, 1, 7, 4, 6, 0, 2,
78>>> 5, 3, 6, 0, 2, 4, 1, 7,
79>>> 5, 3, 6, 0, 7, 1, 4, 2,
80>>> 5, 7, 1, 3, 0, 6, 4, 2,
81>>> 6, 0, 2, 7, 5, 3, 1, 4,
82>>> 6, 1, 3, 0, 7, 4, 2, 5,
83>>> 6, 1, 5, 2, 0, 3, 7, 4,
84>>> 6, 2, 0, 5, 7, 4, 1, 3,
85>>> 6, 2, 7, 1, 4, 0, 5, 3,
86>>> 6, 3, 1, 4, 7, 0, 2, 5,
87>>> 6, 3, 1, 7, 5, 0, 2, 4,
88>>> 6, 4, 2, 0, 5, 7, 1, 3,
89>>> 7, 1, 3, 0, 6, 4, 2, 5,
90>>> 7, 1, 4, 2, 0, 6, 3, 5,
91>>> 7, 2, 0, 5, 1, 4, 6, 3,
92>>> 7, 3, 0, 2, 5, 1, 6, 4,
总共步数:3920
Press Any Key to Continue...
一开始,我使用struct(A)来保存每一个皇后的位置,另外使用了一个struct(B)来保存当前列之前所有列中已放过皇后的位置,以防重复处理;我觉得方法思想上是没有问题的,但是运行的时候一个结果都没有出来,进入了死循环。我发现是往B中插入的数据没有成功,虽然在那个小funcion里边是没问题了,出来之后就回到原样了,因此已放过皇后的位置总是没有保存,每次都回退到之前的位置。
后来,我想到了另外一种实现,不使用struct,使用两个数组,分别保存每一列皇后的位置,已经皇后走过的标志(使用了2的row次方的方法,实际上跟前一个数组差不多),然后按照这个思路的结果,前边4个答案出来了,然后死循环,直到stack overflow。当我仔细分析算法的时候,我发现另一种更简洁一点的实现,只用一个数组,因为每一个数组元素储存的就是该列已经尝试过的最大值,下一次应该从它的下一个位置寻找。按照这个思路实现的结果跟上一个一样,只出来了4个答案(还差了88个)。
我再分析,发现是第一列第一个位置的所有可能情况找出来之后没法跳出循环,寻找第一列第二个位置的情况,于是我添加了
if (i>=ROW && column==1)
break; /*45-46行*/
如果第二列已经找到头了,就跳出。这个结果是得到了88个,看来最后一个位置(第一列)还有问题。于是我再添加了
else if (column==0 && i>5)
break; /*47-48行*/
当回退到第一列的时候,第二列如果序号超过了5,就跳出,因为序号6和7是肯定无法匹配的。这样就没有问题了。
但是这样修改我觉得不够清晰明了,难解释,今早我想除了另外一个办法,在之后某个地方添加
if (coulmn == 0)
break; /*73-74行*/
这是回退的时候如果退到第一列了,说明第一列当前位置已经搜索完毕,可以进入下一个位置了,根据实现,这里的循环就应该出来了。
具体的实现参看如下的源代码:
- /**
- * Author: Hegc Huang
- * Copyright 2008
- */
- #include <stdio.h>
- #include <memory.h>
- #define ROW 8
- #define COLUMN ROW
- int success = 0; /*successful times*/
- void show(int* p)
- {
- int i = 0;
- printf("%2d>>> ", success);
- for (i=0;i<COLUMN ; i++ )
- {
- printf("%d, ", p[i]);
- }
- printf("/n");
- }
- int main(int argc, char *argv[])
- {
- int pieces[COLUMN];
- int row = 0; /*row in the first column*/
- int column = 0; /*the current column*/
- int flag = 0; /*is matched in current column*/
- int i = 0; /*row int current column*/
- int j = 0; /*column from 0 to the one before the current column*/
- int count = 0; /*steps need*/
- /*set the pieces all as -1, [0,COLUMN) represents row in the n-th column*/
- memset(pieces, -1, sizeof(pieces));
- //init (0,0) as 0, and the current column add to the next column
- pieces[column] = 0;
- column++;
- while (row < ROW)
- {
- while (column < COLUMN)
- {
- count++;
- flag = 0;
- i = pieces[column] + 1;
- // if (i>=ROW && column==1)
- // break;
- // else if (column==0 && i>5)
- // break;
- for (i=i; i<ROW ;i++ )
- {
- for (j=0 ;j<column ;j++ )
- {
- if (i==pieces[j] || abs(j-column)==abs(pieces[j]-i))
- {
- flag = 0;
- break;
- }
- flag = 1;
- }
- if (flag)
- break;
- }
- if (flag)
- {
- pieces[column] = i;
- column++;
- }
- else
- {
- pieces[column] = -1;
- column--;
- if (column == 0) /*nowhere to go back*/
- break;
- }
- }/*internal while end*/
- if (flag)
- {
- success++;
- show(pieces);
- flag = 0;
- pieces[column-1] = -1;
- column -= 2;
- }
- else
- {
- memset(pieces, -1, sizeof(pieces));
- column = 0;
- row++;
- pieces[column] = row;
- column++;
- }
- }/*external while end*/
- printf("总共步数:%d/nPress Any Key to Continue.../n", count);
- fflush(stdin);
- getch();
- return 0;
- }
当然,由于没有保存每次的结果的机制,所以每次完成之后都将结果打印出来,按照列的顺序,每一个数字是在列中的编号。
1>>> 0, 4, 7, 5, 2, 6, 1, 3,
2>>> 0, 5, 7, 2, 6, 3, 1, 4,
3>>> 0, 6, 3, 5, 7, 1, 4, 2,
4>>> 0, 6, 4, 7, 1, 3, 5, 2,
5>>> 1, 3, 5, 7, 2, 0, 6, 4,
6>>> 1, 4, 6, 0, 2, 7, 5, 3,
7>>> 1, 4, 6, 3, 0, 7, 5, 2,
8>>> 1, 5, 0, 6, 3, 7, 2, 4,
9>>> 1, 5, 7, 2, 0, 3, 6, 4,
10>>> 1, 6, 2, 5, 7, 4, 0, 3,
11>>> 1, 6, 4, 7, 0, 3, 5, 2,
12>>> 1, 7, 5, 0, 2, 4, 6, 3,
13>>> 2, 0, 6, 4, 7, 1, 3, 5,
14>>> 2, 4, 1, 7, 0, 6, 3, 5,
15>>> 2, 4, 1, 7, 5, 3, 6, 0,
16>>> 2, 4, 6, 0, 3, 1, 7, 5,
17>>> 2, 4, 7, 3, 0, 6, 1, 5,
18>>> 2, 5, 1, 4, 7, 0, 6, 3,
19>>> 2, 5, 1, 6, 0, 3, 7, 4,
20>>> 2, 5, 1, 6, 4, 0, 7, 3,
21>>> 2, 5, 3, 0, 7, 4, 6, 1,
22>>> 2, 5, 3, 1, 7, 4, 6, 0,
23>>> 2, 5, 7, 0, 3, 6, 4, 1,
24>>> 2, 5, 7, 0, 4, 6, 1, 3,
25>>> 2, 5, 7, 1, 3, 0, 6, 4,
26>>> 2, 6, 1, 7, 4, 0, 3, 5,
27>>> 2, 6, 1, 7, 5, 3, 0, 4,
28>>> 2, 7, 3, 6, 0, 5, 1, 4,
29>>> 3, 0, 4, 7, 1, 6, 2, 5,
30>>> 3, 0, 4, 7, 5, 2, 6, 1,
31>>> 3, 1, 4, 7, 5, 0, 2, 6,
32>>> 3, 1, 6, 2, 5, 7, 0, 4,
33>>> 3, 1, 6, 2, 5, 7, 4, 0,
34>>> 3, 1, 6, 4, 0, 7, 5, 2,
35>>> 3, 1, 7, 4, 6, 0, 2, 5,
36>>> 3, 1, 7, 5, 0, 2, 4, 6,
37>>> 3, 5, 0, 4, 1, 7, 2, 6,
38>>> 3, 5, 7, 1, 6, 0, 2, 4,
39>>> 3, 5, 7, 2, 0, 6, 4, 1,
40>>> 3, 6, 0, 7, 4, 1, 5, 2,
41>>> 3, 6, 2, 7, 1, 4, 0, 5,
42>>> 3, 6, 4, 1, 5, 0, 2, 7,
43>>> 3, 6, 4, 2, 0, 5, 7, 1,
44>>> 3, 7, 0, 2, 5, 1, 6, 4,
45>>> 3, 7, 0, 4, 6, 1, 5, 2,
46>>> 3, 7, 4, 2, 0, 6, 1, 5,
47>>> 4, 0, 3, 5, 7, 1, 6, 2,
48>>> 4, 0, 7, 3, 1, 6, 2, 5,
49>>> 4, 0, 7, 5, 2, 6, 1, 3,
50>>> 4, 1, 3, 5, 7, 2, 0, 6,
51>>> 4, 1, 3, 6, 2, 7, 5, 0,
52>>> 4, 1, 5, 0, 6, 3, 7, 2,
53>>> 4, 1, 7, 0, 3, 6, 2, 5,
54>>> 4, 2, 0, 5, 7, 1, 3, 6,
55>>> 4, 2, 0, 6, 1, 7, 5, 3,
56>>> 4, 2, 7, 3, 6, 0, 5, 1,
57>>> 4, 6, 0, 2, 7, 5, 3, 1,
58>>> 4, 6, 0, 3, 1, 7, 5, 2,
59>>> 4, 6, 1, 3, 7, 0, 2, 5,
60>>> 4, 6, 1, 5, 2, 0, 3, 7,
61>>> 4, 6, 1, 5, 2, 0, 7, 3,
62>>> 4, 6, 3, 0, 2, 7, 5, 1,
63>>> 4, 7, 3, 0, 2, 5, 1, 6,
64>>> 4, 7, 3, 0, 6, 1, 5, 2,
65>>> 5, 0, 4, 1, 7, 2, 6, 3,
66>>> 5, 1, 6, 0, 2, 4, 7, 3,
67>>> 5, 1, 6, 0, 3, 7, 4, 2,
68>>> 5, 2, 0, 6, 4, 7, 1, 3,
69>>> 5, 2, 0, 7, 3, 1, 6, 4,
70>>> 5, 2, 0, 7, 4, 1, 3, 6,
71>>> 5, 2, 4, 6, 0, 3, 1, 7,
72>>> 5, 2, 4, 7, 0, 3, 1, 6,
73>>> 5, 2, 6, 1, 3, 7, 0, 4,
74>>> 5, 2, 6, 1, 7, 4, 0, 3,
75>>> 5, 2, 6, 3, 0, 7, 1, 4,
76>>> 5, 3, 0, 4, 7, 1, 6, 2,
77>>> 5, 3, 1, 7, 4, 6, 0, 2,
78>>> 5, 3, 6, 0, 2, 4, 1, 7,
79>>> 5, 3, 6, 0, 7, 1, 4, 2,
80>>> 5, 7, 1, 3, 0, 6, 4, 2,
81>>> 6, 0, 2, 7, 5, 3, 1, 4,
82>>> 6, 1, 3, 0, 7, 4, 2, 5,
83>>> 6, 1, 5, 2, 0, 3, 7, 4,
84>>> 6, 2, 0, 5, 7, 4, 1, 3,
85>>> 6, 2, 7, 1, 4, 0, 5, 3,
86>>> 6, 3, 1, 4, 7, 0, 2, 5,
87>>> 6, 3, 1, 7, 5, 0, 2, 4,
88>>> 6, 4, 2, 0, 5, 7, 1, 3,
89>>> 7, 1, 3, 0, 6, 4, 2, 5,
90>>> 7, 1, 4, 2, 0, 6, 3, 5,
91>>> 7, 2, 0, 5, 1, 4, 6, 3,
92>>> 7, 3, 0, 2, 5, 1, 6, 4,
总共步数:3920
Press Any Key to Continue...
- 八皇后的C语言实现
- 八皇后问题的C语言实现
- 八皇后 c语言实现
- 八皇后 C语言递归实现
- C语言实现“八皇后问题”
- 八皇后C语言
- 八皇后问题,C语言实现,求出第一行第一列有皇后的解
- C语言 八皇后问题
- 八皇后(c语言)
- C语言-八皇后问题
- c语言八皇后问题
- 八皇后 c语言递归实现方法(带注释)
- 八皇后问题(用c语言实现)
- 八皇后GO语言实现
- 皇后问题最快的解法(C语言)八皇后、十六皇后时间在毫秒级
- 八皇后问题-C实现
- 八皇后问题的解决(c语言)
- 八皇后问题,自己写的c语言
- IntelliJ IDEA和Tomcat整合注意事项
- cdata段
- Oracle Trigger
- Oracle 導入導出
- c#中播放声音
- 八皇后的C语言实现
- 《奥多比 PS CS4 官方中文版》(Adobe Photoshop CS4 Extended)繁体中文/简体中文/韩文
- 地震后放假(EarthQuake 13)
- 设计图书管理系统的信息要求;
- 回学校答辨(EarthQuake 14)
- 等着拿毕业证(EarthQuake And Finish school 15)
- Should it be end?(EarthQuake And Finish school 16)
- VB中的Foreach
- 单片机 -- 棋盘扫描、LED控制