ACM:回溯,八皇后问题,素数环

news/2024/7/16 8:14:51

(一)八皇后问题
(1)回溯

#include <iostream>
#include <string>

#define MAXN 100

using namespace std;

int tot = 0, n = 8;
int C[MAXN];

void search(int cur) {
	if(cur == n) ++tot;       //递归边界,仅仅要走到了这里。全部皇后必定不冲突
	else for(int i = 0; i < n; ++i) {
		int ok = 1;
		C[cur] = i;     //尝试把第cur行的皇后放在第i列
		for(int j = 0; j < cur; ++j) {     //检查是否和前面的皇后冲突
			if(C[cur] == C[j] || cur-C[cur] == j-C[j] || cur+C[cur] == j+C[j]) {
				ok = 0;
				break;
			}
		}
		if(ok)  search(cur+1);     //假设合法,则继续递归
	}
}

int main() {
	search(0);
	cout << tot << endl;
	return 0;
}



(2)利用二维数组优化的回溯法

#include <iostream>
#include <string>

#define MAXN 100

using namespace std;

int tot = 0, n = 8;
int vis[3][MAXN], C[MAXN];    

void search(int cur) {
	if(cur == n) ++tot;
	else for(int i = 0; i < n; ++i) {
		if(!vis[0][i] && !vis[1][cur+i] && !vis[2][cur-i+n]) {    //利用二维数组直接推断
			C[cur] = i;
			vis[0][i] = vis[1][cur+i] = vis[2][cur-i+n] = 1;   //改动全局变量
			search(cur+1);
			vis[0][i] = vis[1][cur+i] = vis[2][cur-i+n] = 0;   //这里一定要改回来!
		}
	}
}

int main() {
	memset(vis, 0, sizeof(vis));
	search(0);
	cout << tot << endl;
	return 0;
}

在上面的程序中,vis数组表示已经放置的皇后占领了哪些列、主对角线和副对角线。

一般的在回溯法中,假设改动了全局变量vis数组,那么递归调用结束后一定要改动回来!由于在解答树中,假设下一层不满足条件,那么就须要回溯。那么就要把改动过的vis给改回来,那样,才干继续进行下一次的推断!!!


(二)素数环

题目:输入正整数n,把整数1。2,3,...,n组成一个环。使得相邻两个整数之和均为素数。

输出时从整数1開始逆时针排列。

同一个环应该恰好输出一次。

典型的回溯法,代码例如以下:

#include <iostream>
#include <algorithm>
using namespace std;

const int MAXN = 1000;
int isp[MAXN], vis[MAXN], A[MAXN], n;

int is_prime(int x) {    //推断一个数是否为素数
	for(int i = 2; i*i <= x; ++i) {
		if(x % i == 0) return 0;
	}
	return 1;
}

void dfs(int cur) {
	if(cur == n && isp[A[0] + A[n-1]]) {
		for(int i = 0; i < n; ++i) cout << A[i] << " ";
		cout << endl;
	}else {
		for(int i = 2; i <= n; ++i) {
			if(!vis[i] && isp[i + A[cur-1]]) {
				A[cur] = i;   //数字i满足条件,所以第cur个位置能够放数字i
				vis[i] = 1;
				dfs(cur+1);
				vis[i] = 0;   //跟上题一样。一定不能忘记把vis的值改回来,原因见上一题的代码凝视
			}
		}
	}
}

int main() {
	memset(vis, 0, sizeof(vis));   //递归调用之前,一定要把vis函数清0
	cin >> n;
	for(int i = 2; i <= 2*n; ++i) isp[i] = is_prime(i);   //推断一个数不是质数。为了方便后推断
	A[0] = 1;   //从标题中的规定的第一个数字1开始
	dfs(1);     //所以递归调用位置的1开始,而不是从位置0开始,因为数字第一位置已被确定是1
	return 0;
}




本文转自mfrbuaa博客园博客,原文链接:http://www.cnblogs.com/mfrbuaa/p/5037127.html,如需转载请自行联系原作者



http://www.niftyadmin.cn/n/1904159.html

相关文章

技术不局限于赚钱,还应当保护我们的家人

有一天&#xff0c;我们也会有孩子&#xff1b;有一天&#xff0c;我们也会成为低 x 人口。昨天在电影院看了《正义联盟》&#xff0c;可以容纳上百人的电影院里&#xff0c;只有不到十个人。唯一的观感是&#xff1a;贫穷限制了我们的想象力。这个世界没有超级英雄&#xff0c…

一台Nginx服务器反向代理多个80端口服务器

主要是实现公网IP越来越不足的情况&#xff0c;80端口又是常用端口&#xff0c;只好用Nginx来代理。Nginx服务器安装采用编译:1.pcre 、openssl 、zlib2.其他依赖包配置Nginx主配置文件nginx.conf ,请先备份nginx.conf。** vim nginx.conf** user cent cent; worker_proces…

使用 adr 轻松创建 “程序员友好” 的轻量级文档

是的&#xff0c;我又写了一个 markdown 工具&#xff0c;它对我来说非常有用。上下文在一周里&#xff0c;我看到了一个名为 “轻量级架构决策记录” 的技术实践。在看到了一个简单的示例之后&#xff0c;并阅读了文章《架构决策记录》之后&#xff0c;我开始对于这种工具有了…

在广州想免费学 AI,快来试试这个 AI 开发者实战营

近日&#xff0c;2017 百度世界大会在北京举行&#xff0c;活动吸引了数千名开发者和合作伙伴到场。据介绍&#xff0c;百度 AI 开放平台已开放 80 多项核心 AI 能力。如果你还在为错过百度世界大会而感到遗憾&#xff0c;那接下来的这次活动一定能弥补你的“小遗憾”。今年 10…

一种提高编程效率的『简单方式』

提高编程的效率目的就是&#xff1a;早点下班回家抱女朋友。最近&#xff0c;我觉得好像老了——事情一多、一杂&#xff0c;再加点别人的干扰&#xff0c;就有点记不住。于是乎&#xff0c;当遇到一系列的问题时&#xff0c;我开始写在便利贴上。然而&#xff0c;我却发现了&a…

php table设置tr,在angularjs中如何实现table增加tr的方法

下面我就为大家分享一篇angularjs实现table增加tr的方法&#xff0c;具有很好的参考价值&#xff0c;希望对大家有所帮助。需求&#xff1a;上面是一个table&#xff0c;运用了循环显示。现在的一个需求是&#xff1a;需要在每行添加一个字段&#xff0c;不过不能在同一行显示&…

Spring MVC遭遇checkbox的问题解决方案

Spring MVC遭遇checkbox的问题是&#xff1a;当checkbox全不选时候&#xff0c;则该checkbox域的变量为null&#xff0c;不能动态绑定到spring的controller方法的入参上&#xff0c;并抛出异常。 解决方案&#xff1a; 1、javascript方式提交&#xff0c;提交前拼提交参数串&am…

Linux 系统初始化脚本

Linux 系统初始化脚本 适用于批量部署linux 操作系统&#xff01; #update 20130305 cat sys-init.sh #!/bin/bash #linux system initialization #update 20130305 by dongnan # #关闭不需要的服务 chkconfig atd off chkconfig cups off chkconfig bluetooth off chkc…