码迷,mamicode.com
首页 > 其他好文 > 详细

18年CUG校赛--恶魔的序列

时间:2019-05-14 19:08:31      阅读:140      评论:0      收藏:0      [点我收藏+]

标签:就会   clu   整数   bre   全排列递归   全排列   判断   提示   表示   

问题描述
小龙同学最近为了完成毕业设计头痛不已。巨大的精神压力导致他经常做 噩梦。这天他又做了一个史诗般的噩梦。他梦见自己被困在一个密室中,密室 的门上有一个谜题,只有解开谜题才能打开此门,逃出这个密室,否则就会永 远地被困在密室中,更可怕的是他还会永远的困在梦境中,无法完成毕设,从 而面临毕业危机。 谜题是这样的,给定一个连续的正整数序列 n, n+1, n+2, ..., m,要求通过 调整序列中数字的顺序,将其变成一个“k 度芝麻开门序列”。 一个简单的“2 度芝麻开门序列”可以理解为重新调整一个连续整数序列 的顺序,使得每对相邻两个数之和是一个合数(非质数)。同样的,一个“k 度 芝麻开门序列”就是指调整后序列中所有长度为 2,3, …, k 的连续子序列数字之 和都是合数。例如对于 n=1,m=10 的序列,排列 1,3,5,4,2,6,9,7,8,10 是一个 2 度芝麻开门序列,但是却不是 3 度芝麻开门序列,因为 5+4+2 之和为 11 是质 数。 小龙同学由于被毕业设计榨干了头脑,已经无法再进行思考,所以请你帮 帮他解开谜题,拯救他的毕业设计。
输入 多组输入。每组输入占一行,包括三个正整数 n,m,k, (1<=n<=m<=1000,2<=k<=10)表示序列左右边界和度数,输入由三个整数 0,0,0 结束。 输出 对于每一组输入,输出一个序列,即从 n 到 m 的 k 度芝麻开门序列,以‘,‘ 分隔。如果有多组解,则按照字典序输出第一组(就是说,输出第一个元素最 小的一组,如果第一个元素相同,则输出第二个元素最小的一组,依次类推)。 如果没有解,则输出一行提示:“Your nightmare never ends.”

样例输入

1 10 2

1 10 3

1 10 5

40 60 7

0 0 0

样例输出

1,3,5,4,2,6,9,7,8,10

1,3,5,4,6,2,10,8,7,9

Your nightmare never ends.

40,41,43,42,44,46,45,47,48,50,55,53,52,60,56,49,51,59,58,57,54

解法

有点类似全排列递归的写法,加上一个序列条件的判断。

代码

#include<iostream>
using namespace std;
const int N = 10000;
int vis[N];
int v[1005];
int path[1005];
int n, m, k;
void init() {
	int m = sqrt(N + 0.5);
	memset(vis, 0, sizeof(vis));
	for (int i = 2; i <= m; i++) {
		if (!vis[i])
			for (int j = i * i; j <= N; j += i)
				vis[j] = 1;
	}
}

bool flag = 0;

bool dfs(int pos,int x) {

	path[pos] = x;
	if (pos >= 2) {
		int sum = path[pos], d = pos >k?k:pos;
		for (int i = pos - 1; i > pos - k; i--) {
			sum += path[i];
			if (!vis[sum])return false;
		}
		if (pos == m - n + 1)
		{
			flag = true;
			for (int i = 1; i <= m - n + 1; ++i) {
				printf(i == 1 ? "%d" : ",%d", path[i]);
			}
			cout << endl;
			return true;
		}
	}
	
	
	for (int i = n; i <= m; i++) {
		if (!v[i]) {
			v[i] = 1;
			if (dfs( pos + 1,i))return true;
			v[i] = 0;
		}
	}
	return false;
}

int main() {
	init();

	while (cin>>n>>m>>k&&n!=0)
	{
		flag = false;
		memset(v, 0, sizeof(v));
		for (int i = n; i <= m; ++i) {
			v[i] = 1;
			if (dfs(1,i)) {
				flag = 1;
				break;
			}
			v[i] = 0;
		}
		if(!flag)
		 cout << "Your nightmare never ends." << endl;
	}
   return  0;
}

  

 

18年CUG校赛--恶魔的序列

标签:就会   clu   整数   bre   全排列递归   全排列   判断   提示   表示   

原文地址:https://www.cnblogs.com/gzr2018/p/10863892.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!