Sicily 1002. Anti-prime Sequences dfs
一开始卡时卡得厉害,后来优化了,还是TLM, 看了别人的解题报告, 发现自己写的check函数复杂了用了3个循环,其实两个循环就可以了,还学会了筛选法求素数
#include<iostream>
#include <memory.h>
#include <math.h>
#include <stdio.h>
using namespace std;
int result[1001];
bool used[1001];
bool isprime[10010];
int d, m, n, num;
int dfs(int);
bool isfound;
bool check(int);
void prime_list();
int main()
{
prime_list();
while (cin >> n >> m >> d && !(n== 0 && m == 0 && d==0))
{
isfound = false;
num = m-n+1;
memset(used, false, 1001*sizeof(bool));
dfs(0);
if (isfound)
{
for (int i = 0; i < num-1; i++)
printf("%d,", result[i]);
printf("%d\n", result[num-1]);
}
else
printf("No anti-prime sequence exists.\n");
}
return 0;
}
int dfs(int current)
{
if (isfound) return 0;
if (!check(current)) return 0;
if (current == num) {isfound = true; return 0;}
for (int i = 0; i < num && !isfound; i++)
{
if (!used[i])
{
used[i] = true;
result[current] = n+i;
dfs(current+1);
used[i] = false;
}
}
return 0;
}
bool check(int current)
{
int sum = 0;
if (current <= 1) return true;
for (int i = 0; i < current; i++)
{
sum = 0;
if (i+d < current)
for (int j = 0; j < d; j++)
{
sum += result[i+j];
if (j > 1 && isprime[sum]) return false;
}
else
{
for (int j = i; j < current; j++)
{
sum += result[j];
if (j - i > 0 && isprime[sum]) return false;
}
}
}
return true;
}
//筛选法求1~10000的素数
void prime_list()
{
int i , j;
memset(isprime, true, sizeof(isprime));
isprime[0] = false;
isprime[1] = false;
//注意:合数N的不等于1的最小正因数不大于N的平方根
for ( i = 2; i*i <= 10000; i++)
{
j = 2;
if (isprime[i])
{
while (i*j <= 10000)
{
isprime[i*j] = false;
j++;
}
}
}
}
浙公网安备 33010602011771号