Sicily 1002. Anti-prime Sequences | 深度优先搜索

 
1002. Anti-prime Sequences 
 
Time Limit: 3sec    Memory Limit:32MB
Description

Given a sequence of consecutive integers n,n+1,n+2,...,m, an anti-prime sequence is a rearrangement of these integers so that each adjacent pair of integers sums to a composite (non-prime) number. For example, if n = 1 and m = 10, one such anti-prime sequence is 1,3,5,4,2,6,9,7,8,10. This is also the lexicographically first such sequence. We can extend the definition by defining a degree danti-prime sequence as one where all consecutive subsequences of length 2,3,...,d sum to a composite number. The sequence above is a degree 2 anti-prime sequence, but not a degree 3, since the subsequence 5, 4, 2 sums to 11. The lexicographically .rst degree 3 anti-prime sequence for these numbers is 1,3,5,4,6,2,10,8,7,9.


Input

Input will consist of multiple input sets. Each set will consist of three integers, n, m, and d on a single line. The values of n, m and d will satisfy 1 <= n < m <= 1000, and 2 <= d <= 10. The line 0 0 0 will indicate end of input and should not be processed.


Output

For each input set, output a single line consisting of a comma-separated list of integers forming a degree danti-prime sequence (do not insert any spaces and do not split the output over multiple lines). In the case where more than one anti-prime sequence exists, print the lexicographically first one (i.e., output the one with the lowest first value; in case of a tie, the lowest second value, etc.). In the case where no anti-prime sequence exists, output No anti-prime sequence exists.


Sample Input

1 10 2
1 10 3
1 10 5
40 60 7
0 0 0
 
       
Sample Output
1,3,5,4,2,6,9,7,8,10
1,3,5,4,6,2,10,8,7,9
No anti-prime sequence exists.
40,41,43,42,44,46,45,47,48,50,55,53,52,60,56,49,51,59,58,57,54
思路:见代码注释
代码:
#include<iostream>
#include<string.h>
using namespace std;
const int MAX=10001;// 由于d的上限是10,所以 MAX最大应该是1000(m的上界)的10倍左右,这里取10001 
int m,n,d;
bool exist;
int vis[MAX];
int res[MAX]; 
int pri[MAX];

void init ()//频繁使用在1-10001阶段的素数判断,最好是先打好表存储起来,比较省时间 
{
    memset(pri,0,sizeof(pri));
    pri[1] = 1; //若i是素数则pri[i]为1 
    for ( int i = 2; i <= 100; i++ )
    {
        if ( pri[i] ) continue;
        for ( int j = 2; i * j < 10001; j++ )
            pri[i*j] = 1;
    }
}
bool judge(int step,int i)//判断是否符合规则 
{
    res[step]=i;
    int sum=0;
    int cnt=0;
    for(int j=step; j>=0; j--)
    {
        sum+=res[j];
        ++cnt;
        if(2<=cnt&&cnt<=d && !pri[sum])
        {
            return false;
    	}
    }
    return true;
}
void dfs(int step)
{
	//若在其他已经搜索过的分支中 找到了满足要求的序列,则返回 
	if(exist) return ;
	//若所有数字已经排完序,则返回,这句可以说是和下面的 if(exist) return; 是相对应的 
	if(step==m-n+1) 
	{
		exist=true;
		return ;
	}
	for(int i=n;i<=m;i++)
	{
		if(!vis[i]&&judge(step,i))
		{
			vis[i]=1;
			dfs(step+1);  
			vis[i]=0;                            
		}
		if(exist) return;//没加上这句会WA 
	}
	
}
int main()
{
	init();
	while(cin>>n>>m>>d)
	{
		if(!n&&!m&&!d)break;
		memset(vis,0,sizeof(vis));
	//	memset(res,0,sizeof(res));//由于res每次都会从0开始更新,所以可以偷懒不用清零 
		exist=false;
		dfs(0);//搜索 
		if(exist)
		{
			cout<<res[0];
			for(int i=1;i<=m-n;i++)
				cout<<","<<res[i];
			cout<<endl;
		
		}           	
		else cout<<"No anti-prime sequence exists."<<endl;
	}
}                      



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值