UVa524 Prime Ring Problem(素数环)

news/2024/7/20 20:09:21 标签: 深度优先, 回溯法

1、题目

在这里插入图片描述

2、题意

输入正整数 n n n,把整数1,2,3,…,n 组成一个环,使得相邻两个整数之和均为素数。输出时从整数 1开始逆时针排列。同一个环应恰好输出一次。 n ≤ 16 n \le 16 n16

3、分析

由模型不难得到:每个环对应于 1 ~ n 的一个排列,但排列总数高达 16! = 2 * 1013,生成-测试法会超时吗?进行实验:

for (int i = 2; i <= n * 2; i++) 
	isp[i] = is_prime(i);//生成素数表,加快后续判断
	
for (int i = 0; i < n; i++) 
	A[i] = i + 1; //第一个排列
	
do {
	int ok = 1;
	for (int i = 0; i < n; i++) 
		if(!isp[A[i] + A[(i + 1) % n]]) {  //判断合法性
			ok = 0; 
			break; 
		}

	if(ok) {
		for(int i = 0; i < n; i++) 
			printf("%d ", A[i]); //输出序列
		printf("\n");
	}
} while(next_permutation(A + 1, A + n)); //1的位置不变

运行后发现,当 n = 12 时就已经很慢,而当 n = 16 时无法运行出结果。下面试试回溯法

void dfs(int cur){
	if (cur == n && isp[A[0] + A[n-1]]) { //递归边界。别忘了测试第一个数和最后一个数
		for (int i = 0; i < n; i++) printf("%d ", A[i]); //打印方案
		printf("\n");
	} else {
		for (int i = 2; i <= n; i++) //尝试放置每个数i
			if(!vis[i] && isp[i + A[cur - 1]]){ //如果i没有用过,并且与前一个数之和为素数
				A[cur] = i;
				vis[i] = 1; //设置使用标志
				dfs(cur + 1);
				vis[i] = 0; //清除标志
			}
	}
}

回溯法比生成-测试法快了很多,即使 n = 18 速度也不错。将上面的函数名设为 dfs 并不是巧合——从解答树的角度讲,回溯法正是按照深度优先的顺序在遍历解答树。

提示:如果最坏情况下的枚举量很大,应该使用回溯法而不是生成-测试法。

4、代码实现

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

int is_prime(int x) {
	for(int i = 2; i * i <= x; i++)
    	if(x % i == 0) return 0;
  	return 1;
}

int n, A[50], isp[50], vis[50];
void dfs(int cur) {
	if(cur == n && isp[A[0]+A[n-1]]) {
    	for(int i = 0; i < n; i++) {
      		if(i != 0) printf(" ");
      		printf("%d", A[i]);
    	}
    	printf("\n");
  	} else {
  		for(int i = 2; i <= n; i++)
    		if(!vis[i] && isp[i+A[cur-1]]) {
      			A[cur] = i;
      			vis[i] = 1;
      			dfs(cur+1);
      			vis[i] = 0;
    		}
   	}
}

int main() {
	int kase = 0;
  	while(scanf("%d", &n) == 1 && n > 0) {
    	if(kase > 0) printf("\n");
    	printf("Case %d:\n", ++kase);
    	for(int i = 2; i <= n*2; i++) isp[i] = is_prime(i);
    	memset(vis, 0, sizeof(vis));
    	A[0] = 1;
    	dfs(1);
  	}	
  	return 0;
}

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

相关文章

安装ora2pg遇到如下问题

通过源码安装ora2pg成功后&#xff0c;查询帮助信息报错 [rootlocalhost bin]# ora2pg --help Cant locate open.pm in INC (you may need to install the open module) (INC contains: /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/shar…

国际阿里云CDN加速OSS资源教程!

当您需要加速OSS上的静态资源时&#xff0c;可以通过阿里云CDN加速OSS域名&#xff0c;实现静态资源的访问加速。本文详细介绍了通过CDN控制台实现OSS加速的操作流程和应用场景。 客户价值 阿里云OSS可提供低成本的存储&#xff0c;CDN可以实现静态资源加速分发。使用OSS作为C…

Lintcode 3715 · Lowest Common Ancestor V (最小祖先好题)

3715 Lowest Common Ancestor VPRE Algorithms Medium This topic is a pre-release topic. If you encounter any problems, please contact us via “Problem Correction”, and we will upgrade your account to VIP as a thank you. Description Given a binary tree wit…

【微信小程序】发布投票与用户投票完整讲解

目录 前言 组件功能示例 一、数据库 二、后端接口定义 三、前端准备 3.1 定义连接接口 3.2 Vant Weapp UI 组件库 3.3 授权登录与相关工具 四、小程序编写 4.1 投票组件 WXML WXSS JSON WXJS 效果展示讲解&#xff1a; 4.2 发布投票组件 WXML WXSS JSON WX…

【深度学习】Transformer、GPT、BERT、Seq2Seq什么区别?

请看vcr&#xff1a;https://transformers.run/back/transformer/

数字孪生与智慧城市:开启未来智慧生活

在数字时代的浪潮中&#xff0c;数字孪生技术和智慧城市的理念相互交织&#xff0c;共同塑造了一个更智能、更可持续、更宜居的未来。数字孪生是一项前沿技术&#xff0c;将虚拟世界与现实世界相融合&#xff0c;为城市管理者和市民带来了前所未有的机遇和便捷。 数字孪生模型是…

2023年09月 Python(一级)真题解析#中国电子学会#全国青少年软件编程等级考试

Python等级考试&#xff08;1~6级&#xff09;全部真题・点这里 一、单选题&#xff08;共25题&#xff0c;每题2分&#xff0c;共50分&#xff09; 第1题 下列 Python 语句能够正确输出"学而时习之"五个字的是&#xff1f;&#xff08; &#xff09; A: print “…

el-table添加固定高度height后高度自适应

0 效果 1 添加自定义指令 新建目录src/directive/el-table 在el-table目录下新建文件adaptive.js import { addResizeListener, removeResizeListener } from element-ui/src/utils/resize-event// 设置表格高度const doResize async(el, binding, vnode) > {// 获取表格…