题目大意是给出n,m,d,求n到m的一个序列使得任i(2<=i<=d)个相邻数字和为非素数。 1 <= n < m <= 1000, and 2 <= d <= 10
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 existes.
40,4143,42,44,46,45,47,48,50,55,53,52,60,56,49,51,59,58,57,54
用回溯法AC的代码如下:
// source code of submission 839542, Zhongshan University Online Judge System
// source code of submission 839534, Zhongshan University Online Judge System
#include <stdio.h>
#include <string.h>
int n, m, d;
bool prime[10001]; //素数表
bool visit[1001];
int num[1001]; //记录当前数字集合
bool is_prime(int n)
{
for(int i = 2; i * i <= n; ++i)
{
if(n % i == 0)
return false;
}
return true;
}
//回溯
int dfs(int cur)
{
int i, j, k;
int ok;
int sum;
if(cur == (m - n + 1)) //有解
{
for(i = 0; i < cur - 1; ++i)
{
printf("%d,", num[i]);
}
printf("%d\n", num[i]);
return 1;
}
for(i = n; i <= m; ++i) //从n到m选数字
{
if(!visit[i])//没有访问过
{
num[cur] = i;//选取
ok = 1;
for(k = 2; k <= d; ++k)//判断是否满足条件
{
if(cur >= k - 1)
{
sum = 0;
for(j = cur - k + 1; j <= cur; ++j)
sum += num[j];
if(prime[sum])
ok = 0;
}
else
break;
}
if(ok)//满足条件
{
visit[i] = true;//标记已访问
if(dfs(cur+1))//递归
return 1;
visit[i] = false;//取消标记
}
}
}
return 0;
}
int main()
{
int i;
prime[1] = false;
prime[2] = true;
for(i = 3; i < 10001; ++i)
{
if(is_prime(i))
prime[i] = true;
else
prime[i] = false;
}
while(scanf("%d%d%d", &n, &m, &d) != EOF)
{
if(!n && !m && !d)
break;
memset(visit, false, sizeof(visit));
if(!dfs(0))
{
printf("No anti-prime sequence exists.\n");
}
}
return 0;
}