[解题报告]POJ-2698-八皇后问题

来源:互联网 发布:java修改密码代码 编辑:程序博客网 时间:2024/05/21 09:17
一、题目
2698:八皇后问题

原题链接:http://poj.grids.cn/practice/2698/

时间限制: 10000ms 内存限制: 65536kB
描述
在国际象棋棋盘上放置八个皇后,要求每两个皇后之间不能直接吃掉对方。
输入
无输入。
输出
按给定顺序和格式输出所有八皇后问题的解(见Sample Output)。
样例输入
样例输出
No. 11 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 
 No. 21 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 
 No. 31 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 
 No. 41 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 
 No. 50 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 
 No. 60 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 
 No. 70 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 
 No. 80 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 
 No. 90 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 ...
以下省略...
提示  此题可使用函数递归调用的方法求解。
二、分析   
 1、递归法;2、交表法
八皇后问题经典解析:

八皇后问题,是一个古老而著名的问题,是回溯算法的典型例题。该问题是十九世纪著名的数学家高斯1850年提出:在8X8格的国际象棋上摆放八个皇后,使 其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。 高斯认为有76种方案。1854年在柏林的象棋杂志上不同的作者发表了40种不同的解,后来有人用图论的方法解出92种结果。计算机发明后,有多种方法可 以解决此问题。

摘自百度百科
解题思路:深度搜索加记忆数组
*因为皇后不能处于同一行,同一列,同一斜线(即主对角线和副对角线),所以可以判断出8个皇后分别各占一行
*不妨假设从第一行开始,行数依次加一确定每一行皇后的位置,在下面的程序中cur代表行号,因为我们依次让
*行号加一,所以不会存在行号重叠的现象,接下来只需判断列数和对角线没有发生重叠即可,这里,我们用一个记
*忆状态的数组(vis[][])来存储列和对角线的状态,每次确定一个皇后的位置,首先判断其对应的列和对角线是否
*染色,如果没有染色,则该位置有效,并染色,这样就不会出现列和对角线重叠的问题.
下面重点讲解一下对角线,其原理可用下图说明:

 (格子(i-j)的值标示了主对角线)
同理读者自行可以推出
 (格子(i+j)的值标示了副对角线)
又因为主对角线的值有为负数的情况,所以我们在标记的时候应该加>=7的数,所有值都加了>=7所以标记的效果并没有改变

简化版代码:
1 #include<iostream>
2 using namespace std;
3 bool vis[3][30];//记忆数组判断列,主对角线,副对角线是否被占
4 int ans=0;
5 void dfs(int cur)
6 {
7 if(cur==9)//如果当前行数超过8(表明八个皇后已经放好)则结果加一,返回继续递归
8 {
9 ans++;
10 return ;
11 }
12 //vis[0][i]判断列,vis[i][cur-i+8]判断主对角线,vis[2][cur+i]判断副对角线
13 for(int i=1;i<=8;i++)if(!vis[0][i]&&!vis[1][cur-i+8]&&!vis[2][cur+i])
14 {
15 vis[0][i]=vis[1][cur-i+8]=vis[2][cur+i]=true;
16 dfs(cur+1);//深度搜索
17 vis[0][i]=vis[1][cur-i+8]=vis[2][cur+i]=false;
18 }
19 }
20 int main()
21 {
22 dfs(1);//初始化cur为1,即从第一行开始
23 cout<<""<<ans<<" 种结果."<<endl;
24 system("pause");
25 return 0;
26 }
三、AC源代码
1、递归求解
1 #include<iostream>
2 using namespace std;
3
4 bool vis[3][20];//记忆数组判断列,主对角线,副对角线是否被占
5 int ans=0,num=1;
6 int p=0,pos[8];
7
8 void dfs(int cur);
9 void print();
10
11 int main()
12 {
13 dfs(1);//初始化cur为0,即从第一行开始
14 return 0;
15 }
16
17 void dfs(int cur)
18 {
19 if(cur>8)//如果当前行数超过8(表明八个皇后已经放好)则结果加一,返回继续递归
20 {
21 ans++;
22 print();
23 return;
24 }
25 //vis[0][i]判断列,vis[i][cur-i+8]判断主对角线,vis[2][cur+i]判断副对角线
26 for(int i=1;i<=8;i++)
27 if(!vis[0][i]&&!vis[1][cur-i+8]&&!vis[2][cur+i])
28 {
29 pos[p++]=i;
30 vis[0][i]=vis[1][cur-i+8]=vis[2][cur+i]=true;
31 dfs(cur+1);//深度搜索
32 vis[0][i]=vis[1][cur-i+8]=vis[2][cur+i]=false;
33 p--;
34 }
35 }
36
37 void print()
38 {
39 int i,j;
40 cout<<"No. "<<num++<<endl;
41 for(i=0;i<8;i++)
42 {
43 for(j=0;j<8;j++)
44 if(i==pos[j]-1)
45 cout<<"1 ";
46 else
47 cout<<"0 ";
48 cout<<endl;
49 }
50 /*for(i=0;i<8;i++)
51 cout<<pos[i];
52 cout<<endl;*/
53 }
2、直接交表
1 #include <stdio.h>
2 int pos[736]={1,5,8,6,3,7,2,4,1,6,8,3,7,4,2,5,1,7,4,6,8,2,5,3,1,7,5,8,2,4,6,3,2,4,6,8,3,1,7,5,2,5,7,1,3,8,6,4,2,5,7,4,1,8,6,3,2,6,1,7,4,8,3,5,2,6,8,3,1,4,7,5,2,7,3,6,8,5,1,4,2,7,5,8,1,4,6,3,2,8,6,1,3,5,7,4,3,1,7,5,8,2,4,6,3,5,2,8,1,7,4,6,3,5,2,8,6,4,7,1,3,5,7,1,4,2,8,6,3,5,8,4,1,7,2,6,3,6,2,5,8,1,7,4,3,6,2,7,1,4,8,5,3,6,2,7,5,1,8,4,3,6,4,1,8,5,7,2,3,6,4,2,8,5,7,1,3,6,8,1,4,7,5,2,3,6,8,1,5,7,2,4,3,6,8,2,4,1,7,5,3,7,2,8,5,1,4,6,3,7,2,8,6,4,1,5,3,8,4,7,1,6,2,5,4,1,5,8,2,7,3,6,4,1,5,8,6,3,7,2,4,2,5,8,6,1,3,7,4,2,7,3,6,8,1,5,4,2,7,3,6,8,5,1,4,2,7,5,1,8,6,3,4,2,8,5,7,1,3,6,4,2,8,6,1,3,5,7,4,6,1,5,2,8,3,7,4,6,8,2,7,1,3,5,4,6,8,3,1,7,5,2,4,7,1,8,5,2,6,3,4,7,3,8,2,5,1,6,4,7,5,2,6,1,3,8,4,7,5,3,1,6,8,2,4,8,1,3,6,2,7,5,4,8,1,5,7,2,6,3,4,8,5,3,1,7,2,6,5,1,4,6,8,2,7,3,5,1,8,4,2,7,3,6,5,1,8,6,3,7,2,4,5,2,4,6,8,3,1,7,5,2,4,7,3,8,6,1,5,2,6,1,7,4,8,3,5,2,8,1,4,7,3,6,5,3,1,6,8,2,4,7,5,3,1,7,2,8,6,4,5,3,8,4,7,1,6,2,5,7,1,3,8,6,4,2,5,7,1,4,2,8,6,3,5,7,2,4,8,1,3,6,5,7,2,6,3,1,4,8,5,7,2,6,3,1,8,4,5,7,4,1,3,8,6,2,5,8,4,1,3,6,2,7,5,8,4,1,7,2,6,3,6,1,5,2,8,3,7,4,6,2,7,1,3,5,8,4,6,2,7,1,4,8,5,3,6,3,1,7,5,8,2,4,6,3,1,8,4,2,7,5,6,3,1,8,5,2,4,7,6,3,5,7,1,4,2,8,6,3,5,8,1,4,2,7,6,3,7,2,4,8,1,5,6,3,7,2,8,5,1,4,6,3,7,4,1,8,2,5,6,4,1,5,8,2,7,3,6,4,2,8,5,7,1,3,6,4,7,1,3,5,2,8,6,4,7,1,8,2,5,3,6,8,2,4,1,7,5,3,7,1,3,8,6,4,2,5,7,2,4,1,8,5,3,6,7,2,6,3,1,4,8,5,7,3,1,6,8,5,2,4,7,3,8,2,5,1,6,4,7,4,2,5,8,1,3,6,7,4,2,8,6,1,3,5,7,5,3,1,6,8,2,4,8,2,4,1,7,5,3,6,8,2,5,3,1,7,4,6,8,3,1,6,2,5,7,4,8,4,1,3,6,2,7,5};
3 int main()
4 {
5 int i,j,n=92;
6 while(n--)
7 {
8 printf("No. %d\n",92-n);
9 for(i=0;i<8;i++)
10 {
11 for(j=0;j<8;j++)
12 if(i==pos[(91-n)*8+j]-1)
13 printf("1 ");
14 else
15 printf("0 ");
16 printf("\n");
17 }
18 }
19 return 0;
20 }




<script>window._bd_share_config={"common":{"bdSnsKey":{},"bdText":"","bdMini":"2","bdMiniList":false,"bdPic":"","bdStyle":"0","bdSize":"16"},"share":{}};with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)];</script>
阅读(1265) | 评论(0) | 转发(0) |
0

上一篇:程序员必看

下一篇:八皇后

相关热门文章
  • A sample .exrc file for vi e...
  • IBM System p5 服务器 HACMP ...
  • 游标的特征
  • busybox的httpd使用CGI脚本(Bu...
  • Solaris PowerTOP 1.0 发布
给主人留下些什么吧!~~
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 顺产后子宫脱垂怎么办 顺产完子宫脱垂怎么办 额头长了个鱼鳞怎么办 脸上长了很多痣怎么办 做过狐臭的疤痕怎么办 痤疮留下的红印怎么办 脸上疤掉了黑印怎么办 脸上有黑色的疤怎么办 一只眼睛外斜视怎么办 残币银行不给换怎么办 手上有多套房的怎么办 长了两层脚指甲怎么办 指甲长了两层怎么办 脚趾甲长了两层怎么办 产妇气血虚没奶怎么办 哺乳期气血不足奶水少怎么办 刚怀孕喝了啤酒怎么办 受风怎么办最快最有效 孕妇后背受风了怎么办 肩膀和后背受风怎么办 手指关节杵肿了怎么办 骨关节退行性变怎么办 疼风脚趾肿了怎么办 痛风脚右侧肿了怎么办 痛风引起的脚肿怎么办 老人腰闪了该怎么办 腰闪了站不起来怎么办 又怕冷又爱上火怎么办 肝上多发小囊肿怎么办 5岁宝宝咳嗽厉害怎么办 5岁宝宝咳嗽有痰怎么办 生川乌外贴中毒怎么办 7个月宝宝流鼻涕怎么办 脸上皮肤毛孔粗大有黑头怎么办 嗓子长了个囊肿怎么办 食管胃粘膜异位怎么办 狗狗肿瘤破了怎么办 婴儿胃食道反流怎么办 小儿胃食道反流怎么办 放疗后咳嗽痰多怎么办 胃息肉是恶性的怎么办