2017-8-3
题目描述
输出长度为N的特殊质数,即前1至N项所表示的数均为质数
解答
用dfs求解即可
代码
/*
ID: 18795871
PROG: sprime
LANG: C++
*/
#include<iostream>
#include<fstream>
#include<cmath>
using namespace std;
ifstream fin("sprime.in");
ofstream fout("sprime.out");
int cnt=1,N;
long k=10;
bool is_prime(long n){ //判断n是否为质数
if (n==0||n==1) return false;
if (n==2||n==3) return true;
long i;
for (i=2;i<=sqrt(n);i++){
if (n%i==0) return false;
}
return true;
}
void dfs(long n){
if (!is_prime(n)||cnt>N) return ;
if (cnt==N){
fout<<n<<endl;
return ;
}
for (int i=1;i<=9;i+=2){
cnt++;
n=n*k+i;
dfs(n);
n=(n-i)/k;
cnt--;
}
}
int main(){
fin>>N;
cnt=1;
dfs(2);
cnt=1;
dfs(3);
cnt=1;
dfs(5);
cnt=1;
dfs(7);
}
不难想出,直接枚举出所有的情况,然后判断是否是素数即可,然后呢?!超时了!于是我想着进行优化一下,那就是如果说第一位不是素数的话,就直接加m/10这么大,因为当最后到一位的时候,必须保证是素数;然后呢?还是超时!于是变成了前两位必须是素数,还是超时!
/*
ID: 18795871
PROG: sprime
LANG: C++
*/
#include<iostream>
#include<fstream>
#include<cstring>
using namespace std;
ifstream fin("sprime.in");
ofstream fout("sprime.out");
typedef long long ll;
const int N = 100;
bool f[N+1];
int n;
ll m;
bool isprime(ll p){
if (p<2) return false;
for (ll i=2;i*i<=p;i++){
if (p%i==0) return false;
}
return true;
}
bool res(ll p){
ll q=p;
while (q){
if (!isprime(q)) return false;
q/=10;
}
return true;
}
int main(){
memset(f,true,sizeof(f));
f[0]=f[1]=false;
for (int i=2;i<=N;i++){
if (f[i]){
for (int j=2*i;j<=N;j+=i){
f[j]=false;
}
}
}
while (fin>>n){
m=1;
while (n){
m*=10;
n--;
}
for (ll i=m/10;i<m;){
if (!f[i*10/m]){
if (m/10>0) i+=m/10;
else i++;
continue;
}
if (!f[i*100/m]){
if (m/100>0) i+=m/100;
else i++;
continue;
}
if (res(i)) fout<<i<<endl;
i++;
}
}
return 0;
}
上面是超时的代码!
可能还是需要转换一下思路:我们在进行深搜的时候,如果当前不满足题意的话,可以立即return掉,不继续往下了;那么在这里,我们从前往后走,如果说当前的值不满足是素数的话,我们也没有必要再继续下去了!
/*
ID: 18795871
PROG: sprime
LANG: C++
*/
#include<iostream>
#include<fstream>
#include<cstring>
using namespace std;
ifstream fin("sprime.in");
ofstream fout("sprime.out");
typedef long long ll;
const int N = 10;
int n;
bool isprime(ll p){
if (p<2) return false;
for (ll i=2;i*i<=p;i++){
if (p%i==0) return false;
}
return true;
}
void dfs(int step,ll sum){
if (!isprime(sum)) return ;
if (step==n){
fout<<sum<<endl;
return ;
}
for (int i=1;i<N;i++){
dfs(step+1,sum*10+i);
}
}
int main(){
while (fin>>n){
dfs(1,2);
dfs(1,3);
dfs(1,5);
dfs(1,7);
}
return 0;
}
深搜剪枝的速度还是快啊!