DFS专练
2016-02-17 11:50
155 查看
一、N皇后问题
问题描述:
在n×n格的棋盘上放置彼此不受攻击的n个皇后。按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。n后问题等价于在n×n的棋盘上放置n个皇后,任何2个皇后不能在同一行或同一列或同一斜线上。
思路:
要解决N皇后问题,其实就是要解决好怎么放置这n个皇后,每一个皇后与前面的所有皇后不能在同一行、同一列、同一对角线,我们可以以行优先,就是说皇后的行号按顺序递增,只考虑第i个皇后放置在第i行的哪一列,所以在放置第i个皇后的时候,可以从第1列判断起,如果可以放置在第1个位置,则跳到下一行放置下一个皇后。如果不能,则跳到下一列...直到最后一列,如果最后一列也不能放置,则说明此时放置方法出错,则回到上一个皇后向之前放置的下一列重新放置。此即是回溯法的精髓所在。当第n个皇后放置成功后,即得到一个可行解,此时再回到上一个皇后重新放置寻找下一个可行解...如此后,即可找出一个n皇后问题的所有可行解。
代码:
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1016
问题描述:
给定一个数n,有1到n共n个自然数,使这n个自然数组成一个环,要求环中相邻两个数之和为素数,求能够组成这种环的所有情况。
比如n=8,满足条件的素数环有:
1 2 3 8 5 6 7 4
1 2 5 8 3 4 7 6
1 4 7 6 5 8 3 2
1 6 7 4 3 8 5 2
共4种可能。
思路:
对每一个位置的数进行循环遍历,每次都把1到n搜索一遍,符合条件就填进去(记录下来),扫描下一个位置的数字,不符合条件的就跳过。
代码:
问题描述:
在n×n格的棋盘上放置彼此不受攻击的n个皇后。按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。n后问题等价于在n×n的棋盘上放置n个皇后,任何2个皇后不能在同一行或同一列或同一斜线上。
思路:
要解决N皇后问题,其实就是要解决好怎么放置这n个皇后,每一个皇后与前面的所有皇后不能在同一行、同一列、同一对角线,我们可以以行优先,就是说皇后的行号按顺序递增,只考虑第i个皇后放置在第i行的哪一列,所以在放置第i个皇后的时候,可以从第1列判断起,如果可以放置在第1个位置,则跳到下一行放置下一个皇后。如果不能,则跳到下一列...直到最后一列,如果最后一列也不能放置,则说明此时放置方法出错,则回到上一个皇后向之前放置的下一列重新放置。此即是回溯法的精髓所在。当第n个皇后放置成功后,即得到一个可行解,此时再回到上一个皇后重新放置寻找下一个可行解...如此后,即可找出一个n皇后问题的所有可行解。
代码:
#include<stdio.h> #include<math.h> int n; int sum=0; int a[20]; //表示放置皇后的列数 int check(int k) { int i; for(i=0;i<k;i++) //判断是否和前边几行放置的皇后产生冲突 if ( a[k]==a[i] || fabs(k-i)==fabs(a[k]-a[i]))// 列是否冲突 || 对角线是否冲突 return 0; return 1; } void dfs(int row) { int i; if(row==n) sum++; else { for(i=0;i<n;i++) { a[row]=i; //表示第row个皇后放在第row行第i列 if(check(row)) // 判断第row行皇后能否放置 dfs(row+1); //如果能放置,再判断下一行 } } } int main () { scanf("%d",&n); dfs(0); //从第一行开始搜索 printf("%d\n",sum); return 0; }二、素数环问题(HDU 1016)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1016
问题描述:
给定一个数n,有1到n共n个自然数,使这n个自然数组成一个环,要求环中相邻两个数之和为素数,求能够组成这种环的所有情况。
比如n=8,满足条件的素数环有:
1 2 3 8 5 6 7 4
1 2 5 8 3 4 7 6
1 4 7 6 5 8 3 2
1 6 7 4 3 8 5 2
共4种可能。
思路:
对每一个位置的数进行循环遍历,每次都把1到n搜索一遍,符合条件就填进去(记录下来),扫描下一个位置的数字,不符合条件的就跳过。
代码:
#include <stdio.h> #include <string.h> int flag[30]; //标记已经选过的数,1为选,0为未选。 int a[100]; //存放自然数 int n; int check(int x) //判断是否为素数 { int i; for(i=2;i<x;i++) if(x%i==0) return 0; return 1; } void DFS(int k,int index) { int i; a[k]=index;flag[index]=1; //一开始先默认选index放在第k个位置,并将flag置1; if(k==n) { if(check(a[k]+a[1])) //判断第一个和最后一个是否满足条件 { printf("1"); for(i=2;i<=n;i++) //如果满足说明搜索结束,输出结果 printf(" %d",a[i]); printf("\n"); } return ; } for(i=1;i<=n;i++) //每回从第一个开始搜索 { if(!flag[i]&&check(a[k]+i)) { DFS(k+1,i); flag[i]=0; //注意回溯 } } return ; } int main() { int t=1; while(scanf("%d",&n)!=EOF) { printf("Case %d:\n",t++); memset(flag,0,sizeof(flag)); //标志位数组清0; DFS(1,1); printf("\n"); } return 0; }
相关文章推荐
- 江湖问题研究-- intent传递有没有大小限制,是多少?
- ffmpeg对H.264进行rtp打包
- windows 自启动脚本并注册服务
- Android AIDL用法解析
- [计算几何笔记3]最小圆覆盖
- 反汇编异常定位
- 借助共享缓存redis实现分布式锁
- libevent的使用(socket)
- jfinal_BLOG v1.0
- 秒杀DX12!Vulkan 1.0规范正式发布
- 多核CPU的春天:Vulkan实测 完爆OpenGL
- Thrift入门及Java实例演示
- java 单例模式(Singleton)
- phpredisAdmin
- Android studio 自定义注释模板
- Ubuntu14.04安装tomcat7.0和jdk1.7
- Mysql常用命令详解
- Python 17.1 HTTP协议简介
- Tomcat学习—Tomcat的server.xml配置文件
- hdu4035 概率DP求期望