Prime Path素数筛与BFS动态规划

埃拉托斯特尼筛法(sieve of Eratosthenes ) 是古希腊数学家埃拉托斯特尼发明的计算素数的方法。对于求解不大于n的所有素数,我们先找出sqrt(n)内的所有素数p1到pk,其中k = sqrt(n),依次剔除Pi的倍数,剩下的所有数都是素数。
具体操作如上述 图片所示。
C++实现
#include<iostream>
#include<vector>
using namespace std;
int main() {
int n;
cin >> n;
vector<bool> isprime(n + 5, true);
vector<int> ans;
for (int i = 2; i <= n; i++) {
if (isprime[i]) {
ans.push_back(i);
for (int j = i * i; j <= n; j += i)isprime[j] = false;
}
}
for (auto i : ans)cout << i << " ";
cout << endl;
return 0;
}
整除问题
给定n,a求最大的k,使n!可以被ak整除但不能被a(k+1)整除。
输入描述
两个整数n(2<=n<=1000),a(2<=a<=1000)
输出描述
示例1
输入
555 12
输出
274
#include<iostream>
#include<vector>
#include<map>
using namespace std;
int main() {
int n, a, temp;
int ans = 0x7fffffff;
cin >> n >> a;
vector<bool> isprime(1010, true);
vector<int> prime; //素数列表
map<int, int> primecntnp; //存储n!的质因子的指数
map<int, int> primecnta; //存储a的质因子的指数
for (int i = 2; i <= 1010; i++) { //采用素数筛选出前1010个数中的素数,并将map初始化
if (isprime[i]) {
prime.push_back(i);
primecntnp[i] = primecnta[i] = 0;
for (int j = i * i; j <= 1010; j += i)isprime[j] = false;
}
}
//4! = 24 = 1*2*3*4 = 2*2*2*3
for (int i = 0; i < prime.size(); i++) { //对n!进行因式分解
temp = n;
while (temp) { //按照p、p*p、p*p*p来进行因式分解
primecntnp[prime[i]] += temp / prime[i];
temp /= prime[i];
}
}
for (int i = 0; i < prime.size(); i++) { //对a进行因式分解
temp = a;
while (temp % prime[i] == 0) {
primecnta[prime[i]]++;
temp /= prime[i];
}
if (primecnta[prime[i]] == 0)continue; //a里面不存在的则无法提供
if (primecntnp[prime[i]] / primecnta[prime[i]] < ans)ans = primecntnp[prime[i]] / primecnta[prime[i]];
}//找到最小的指数,便是最大的k值
cout << ans << endl;
return 0;
}
/*
555 12
274
*/
拓展
Prime Path素数筛与BFS动态规划的综合应用
问题 POJ
Description
The ministers of the cabinet were quite upset by the message from the Chief of Security stating that they would all have to change the four-digit room numbers on their offices.
— It is a matter of security to change such things every now and then, to keep the enemy in the dark.
— But look, I have chosen my number 1033 for good reasons. I am the Prime minister, you know!
— I know, so therefore your new number 8179 is also a prime. You will just have to paste four new digits over the four old ones on your office door.
— No, it’s not that simple. Suppose that I change the first digit to an 8, then the number will read 8033 which is not a prime!
— I see, being the prime minister you cannot stand having a non-prime number on your door even for a few seconds.
— Correct! So I must invent a scheme for going from 1033 to 8179 by a path of prime numbers where only one digit is changed from one prime to the next prime.Now, the minister of finance, who had been eavesdropping, intervened.
— No unnecessary expenditure, please! I happen to know that the price of a digit is one pound.
— Hmm, in that case I need a computer program to minimize the cost. You don’t know some very cheap software gurus, do you?
— In fact, I do. You see, there is this programming contest going on… Help the prime minister to find the cheapest prime path between any two given four-digit primes! The first digit must be nonzero, of course. Here is a solution in the case above.
1033
1733
3733
3739
3779
8779
8179
The cost of this solution is 6 pounds. Note that the digit 1 which got pasted over in step 2 can not be reused in the last step – a new 1 must be purchased.
Input
One line with a positive number: the number of test cases (at most 100). Then for each test case, one line with two numbers separated by a blank. Both numbers are four-digit primes (without leading zeros).
Output
One line for each case, either with a number stating the minimal cost or containing the word Impossible.
Sample Input
3
1033 8179
1373 8017
1033 1033
Sample Output
6
7
0
问题大意
从一个素数换到另一个素数,每次只能换一个数字(一位)且换后的每次都是素数。求最小次数?
C++代码
#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
const int maxn = 10000;
bool isprime[maxn + 1];
int dp[maxn + 1];
int getNext(int num, int t, int change){
//num : 当前的数,t当前的位置,change是改变位的值
if(t == 0) return num / 10 * 10 + change; //最低位
else if(t == 1) return num /100 * 100 + change * 10 + num % 10;
else if(t == 2) return num /1000 * 1000 + change * 100 + num % 100;
else return change * 1000 + num % 1000;
}
int main(){
fill(isprime+2, isprime + maxn, true);
for(int i = 2; i <= maxn; i++){
if(isprime[i]){
for(int j = i * i; j <= maxn; j += i){
isprime[j] = false;
}
}
}//打表
int T;
cin>>T;
while(T--){
int a, b;
cin>>a>>b;
fill(dp, dp + maxn, 0x3f);
dp[a] = 0; //记录从一个prime跳跃到另一个prime所需的最少次数
queue<int> q;
q.push(a);
while(!q.empty()){
int cur = q.front(); //取出队列的第一个
q.pop();
for(int i = 0; i < 4; i++){
for(int j = 0; j < 10; j++){
if(i == 3 && j == 0) continue; //
int next = getNext(cur, i, j); //替换
if(isprime[next] == false || dp[next] <= dp[cur]) continue;
// 不是素数不行,如果到next已经有更小的那也不用这个变换路径了
dp[next] = dp[cur] + 1;
q.push(next);
}
}
}
cout<<dp[b]<<endl;
}
return 0;
}
/*
3
1033 8179
1373 8017
1033 1033
*/
Prime Path素数筛与BFS动态规划的更多相关文章
- POJ 3126 Prime Path 素数筛,bfs
题目: http://poj.org/problem?id=3126 困得不行了,没想到敲完一遍直接就A了,16ms,debug环节都没进行.人品啊. #include <stdio.h> ...
- Prime Path(POJ - 3126)【BFS+筛素数】
Prime Path(POJ - 3126) 题目链接 算法 BFS+筛素数打表 1.题目主要就是给定你两个四位数的质数a,b,让你计算从a变到b共最小需要多少步.要求每次只能变1位,并且变1位后仍然 ...
- Prime Path(素数筛选+bfs)
Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 9519 Accepted: 5458 Description The m ...
- POJ - 3126 Prime Path 素数筛选+BFS
Prime Path The ministers of the cabinet were quite upset by the message from the Chief of Security s ...
- Prime Path (poj 3126 bfs)
Language: Default Prime Path Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 11703 Ac ...
- POJ 3216 Prime Path(打表+bfs)
Prime Path Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 27132 Accepted: 14861 Desc ...
- Prime Path(POJ 3126 BFS)
Prime Path Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 15325 Accepted: 8634 Descr ...
- [POJ268] Prime Distance(素数筛)
/* * 二次筛素数 * POJ268----Prime Distance(数论,素数筛) */ #include<cstdio> #include<vector> using ...
- POJ 3126 - Prime Path - [线性筛+BFS]
题目链接:http://poj.org/problem?id=3126 题意: 给定两个四位素数 $a,b$,要求把 $a$ 变换到 $b$.变换的过程每次只能改动一个数,要保证每次变换出来的数都是一 ...
随机推荐
- 使用python pip安装工具组件包:出现 requests File “<stdin>",line 1 pip install xxx ^ SyntaxError:invalid syntax
最近想要试试python ,软件安装完成了,但是,import 组件包时,出了问题,一直不得解:安装pycharm 工具感觉麻烦,不想安装那些,只想单纯使用python . 问题复现: 1.Windo ...
- R - Cow and Message CodeForces - 1307C
思路对了,但是不会写. 等差数列长度不是1就是2,所以不是一个字母就是俩字母,一开始写的时候直接枚举两个字母,然后让次数相乘.这样是不对的,比如abaabb,字母ab的个数应该是3+2+2,因该是每一 ...
- ROM定制开发教程-Android adb命令用法与实例解析
一.什么是ADB Android Debug Bridge(adb)是一个命令行工具,可让您与模拟器或连接的Android设备进行通信.您可以在android sdk / platform-tools ...
- .Net Core Send Email
1.安装Nuget包MailKit,引用命名空间. using MailKit.Net.Smtp; using MimeKit; 注意:引用MailKit对应最新版本 2.定义收发地址和标题 Mime ...
- testNG 预期异常、忽略测试、超时测试
通过@Test 注解的参数值实现如下的几种测试 一.通过 @Test(expectedExceptions=异常类名) 参数实现到达 预期指定的异常效果 @Test(expectedException ...
- 使用HashMap或Hashset优化使用循环判断字符串中是否含有重复元素
原本遇到判断字符串中是否含有重复元素的问题总是使用for循环遍历进行判断,这一方法则需要O(n3)的时间复杂度,如果本身方法处于几个循环中,就会指数倍增加时间复杂度.类似于如下代码: String[] ...
- 【高频 Redis 面试题】Redis 事务是否具备原子性?
一.Redis 事务的实现原理 一个事务从开始到结束通常会经历以下三个阶段: 1.事务开始 客户端发送 MULTI 命令,服务器执行 MULTI 命令逻辑. 服务器会在客户端状态(redisClien ...
- 进阶 Linux基本命令-1
vmware三种网络模式1,桥接虚拟机直接连接外网,局域网.宿主机电脑不提供路由. 2,NAT网络地址转换,家庭网 3,host only 只能和宿主电脑打交道 Linux命令形式 命令 +[参数]+ ...
- php环境兼容性问题---压缩格式及其配置简介
php环境兼容性问题-- 内容编码错误 无法显示您尝试查看的页面,因为它使用了无效或者不支持的压缩格式. 请联系网站的所有者以告知此问题. 以前也遇到过同样的问题,记得是PHP代码ob_start(' ...
- Linux系统进入救援模式
由于现在很多的服务器都是用的RedHat,CentOS也比较多,这里就介绍CentOS6.6的救援模式. 有很多人的linux在用的时候不小心修改了某个权限,导致系统启动不起来,下面我就来为大家解决一 ...