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$.变换的过程每次只能改动一个数,要保证每次变换出来的数都是一 ...
随机推荐
- 【Tool】Windows系统安装Maven依赖管理工具
安装Maven依赖管理工具 官网下载地址:http://maven.apache.org/download.cgi 系统环境要求: [JDK]Maven3.3版本+需要JDK1.7版本以上支持 [内存 ...
- 移动硬盘临时文件太多怎么办,python黑科技帮你解决
前言 文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者: 星安果 PS:如果想了解更多关于python的应用,可以私信我,或者 ...
- 关于树的重心--POJ 1655
树的重心的定义: 在一棵树中,找到一个点,其所有的子树中最大的子树节点数最少,那么这个点就是这棵树的重心,删去重心后,生成的多棵树尽可能平衡. 通俗来说就是以这个点为根节点,找到他最大的衣蛾子树,然后 ...
- python基础--str.split
string = 'This +is -a /string' process = string.split('-') process1 = string.split('-')[-1]#-1和-2可能存 ...
- Linux命令:chown
说明: 将指定文件的拥有者改为指定的用户或组. 语法: chown [-cfhvR] [--help] [--version] user[:group] file... 参数: user : 新的文件 ...
- Asp.Net Core 3.0 学习3、Web Api 文件上传 Ajax请求以及跨域问题
1.创建Api项目 我用的是VS2019 Core3.1 .打开Vs2019 创建Asp.Net Core Web应用程序命名CoreWebApi 创建选择API 在Controller文件夹下面添加 ...
- linux CVE-2019-13272 本地特权漏洞
漏洞描述 在5.1.17之前的Linux内核中,kernel / ptrace.c中的ptrace_link错误地处理了想要创建ptrace关系的进程的凭据记录,这允许本地用户通过利用父子的某些方案来 ...
- 漫谈LiteOS-端云互通组件-MQTT开发指南(下)
1.介绍 SDK简介 Agent Tiny是部署在具备广域网能力.对功耗/存储/计算资源有苛刻限制的终端设备上的轻量级互联互通中间件,您只需调用API接口,便可实现设备快速接入到物联网平台以及数据上报 ...
- 面试官:你对Redis缓存了解吗?面对这11道面试题你是否有很多问号?
前言 关于Redis的知识,总结了一个脑图分享给大家 1.在项目中缓存是如何使用的?为什么要用缓存?缓存使用不当会造成什么后果? 面试官心理分析 这个问题,互联网公司必问,要是一个人连缓存都不太清楚, ...
- Jetson AGX Xavier刷机
1. 准备一台电脑做主机(host),运行Ubuntu系统,我用的是虚拟机,运行的是Ubuntu 18.04系统. 2. 主机更换apt-get源,参见https://www.cnblogs.com/ ...