您的位置:首页 > 其它

[2016/7/9][USACO1.5][dp]Superprime Rib

2016-07-09 19:25 190 查看
题目链接:http://train.usaco.org/usacoprob2?a=gR1up10aYLj&S=sprime

题目大意:让你计算n(n在1,8之间)位的,依次抹去它最后一位数字,每次所得到的数仍然是质数的数字。

一些想法:

开始想先用素数筛选出质数,在其中找满足条件的数字。(完全被上一道题带着思路走了

后来想想太暴力了啊喂!1e8的数组开不起啊喂!

开始仔细想题目,这个时候发现,不就是状态依次叠加吗!从1开始,先列出满足条件的数,再以1为基础,算2位满足条件的。以此类推直至到n。在过程中只需要为前一个状态添加尾数,判断是不是素数就好。

这是一道送分题啊同学们!!不就是记忆化搜索嘛!!

就算用了很小学生的素数判断方法,速度还是很快的。毕竟越到后面虽然数字位数越大,但是其数量却减小了。

于是开vector,造一个哈希表,然后打表就好了!

代码:
/*
ID: 49743541
LANG: C++
TASK: sprime
*/
#include <stdio.h>
#include <math.h>
#include <vector>
using namespace std;
vector<int> list[9];
void init(){
list[1].push_back(2);
list[1].push_back(3);
list[1].push_back(5);
list[1].push_back(7);
}
bool isprime(int num){
int s = sqrt(num);
for(int i = 2; i<=s; i++){
if(!(num%i))
return false;
}
return true;
}
int n;
int a[5] = {1,3,5,7,9};
int main(){
freopen("sprime.in", "r", stdin);
freopen("sprime.out", "w", stdout);
init();
scanf("%d",&n);
int j,k;
int A;
for(int i = 2;i<=n;i++){
for(j = 0;j<list[i-1].size();j++){
A = list[i-1][j]*10;
for(k=0;k<5;k++){
if(isprime(A+a[k]))
list[i].push_back(A+a[k]);
}
}
}
for(int i = 0;i<list
.size();i++)
printf("%d\n",list
[i]);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: