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++; } } } }