一开始看这题不敢做,因为怕超时,毕竟给的时间是3s。后来就试着做下,发现其实这题并不算难。反正我想到的就是深搜+回溯。结果ac~~~
这个题有个地方要注意的就是题目中说all consecutive subsequences of length 2,3,...,d sum to a composite number,是2~d个连续的都要满足,不仅仅是d个。还有就是先生成素数表,因为这题频繁的检测是否是素数,有素数表可以提高效率。素数表也不大。因为最大数是1000,d最大是10,那么连续的10个相加也不超过10000,所以这个可以有。
#include <iostream>
#include <cstring>
using namespace std;
const int N = 10000;
int n, m, d;
int ans[1100]; //保存答案
bool prime[N]; //素数表
bool vis[1100]; //访问标识
bool f; //标记是否找到答案
void get_prime()
{
memset(prime, true, sizeof(prime));
for (int i = 2; i <= 100; i++) {
if (prime[i]) {
for (int j = 2; j*i <= N; j++)
prime[j*i] = false;
}
}
}
bool check_prime(int cnt)
{
int sum = ans[cnt];
int j = cnt - 1;
for (int i = 2; i <= d && j >= 0; i++, j--) {
sum += ans[j];
if (prime[sum])
return false;
}
return true;
}
void dfs(int cnt)
{
if (cnt == m-n+1) {
f = true;
return ;
}
for (int i = n; i <= m; i++) {
if (vis[i])
continue;
ans[cnt] = i;
if (check_prime(cnt))
{
vis[i] = true;
dfs(cnt+1);
if (f) { //已经找到答案就直接返回!
return;
}
vis[i] = false;
}
}
}
int main()
{
get_prime();
while (cin >> n >> m >> d) {
if (n == 0)
break;
int cnt = 0;
f = false;
memset(vis, false, sizeof(vis));
dfs(cnt);
if (f) {
for (int i = 0; i < m-n; i++) {
cout << ans[i] << ',';
}
cout << ans[m-n] << endl;
}
else
cout << "No anti-prime sequence exists.\n";
}
return 0;
}