目录

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

目录

Sicily 1002 Anti-prime Sequences(深度优先搜索)

//深度优先搜索 //这道题最大的收获就是学会了深搜的卡时 //TLE了N次之后,看了论坛上赵大牛的指点,用卡时就过了,0.14MS //在做深搜题的时候,有些题目是不需要搜索那么多次的,当超过某个次数时可以当做搜索不出答案了。 //这样的做法虽然无法保证正确性,但是可以大大提高效率 //因此在这道题用了t这个全局变量记录搜索的次数,当t超过4000次时,dfs直接return,不用再搜索了,这样就不会TLE了 #include #include using namespace std; const int MAXP = 50000; bool isPrime[MAXP]; int prime[MAXP]; bool used[1010]; int ans[1010]; int n,m,d,t,sum; bool ok; void primeList()//筛法素数表 { memset(isPrime,true,sizeof(isPrime)); for(int i = 2;i <= MAXP;++i) { if(isPrime[i]) prime[++prime[0]] = i; for(int j = 1,k;j <= MAXP && (k = i * prime[j]) <= MAXP;++j) { isPrime[k] = false; if(i % prime[j] == 0) break; } } } bool check(int len)//检查当前答案是否满足条件 { int sum; if(len <= 1) return true; for(int i = 0;i < len;++i) { sum = 0; if(i <= len - d)//当每段都能达到d这么长的时候 { for(int j = i;j - i + 1<= d ;++j) { sum += ans[j]; if(j-i+1 > 1 && isPrime[sum]) return false;//必须两个数字之和以上才开始判断 } } else//注意补充检测ans后面几位长度小于d的和是否为合数 { for(int j = i;j < len;++j) { sum += ans[j]; if(j-i+1 > 1 && isPrime[sum]) return false;//必须两个数字之和以上才开始判断 } } } return true; } void dfs(int u) { ++t;//卡时变量 if(t > 4000) return;//当超过4000次时就跳出,这个数字随便搞个,我输入4000发现1 1000 10这个数据能通过,证明4000足够了 if(ok) return; if(!check(u)) return; if(u== m - n + 1) { ok = 1; return; } for(int i = n;i <= m && !ok;++i) { if(used[i]) continue; ans[u] = i; used[i] = 1; dfs(u+1); used[i] = 0; } } void print() { printf("%d",ans[0]); for(int i = 1;i < m-n+1;++i) { printf(",%d",ans[i]); } printf("/n"); } int main() { primeList(); while(scanf("%d%d%d",&n,&m,&d) && n != 0) { ok = 0; t = 0; memset(used,0,sizeof(used)); dfs(0); if(ok) print(); else printf(“No anti-prime sequence exists./n”); } return 0; }