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$.变换的过程每次只能改动一个数,要保证每次变换出来的数都是一 ...
随机推荐
- Treasure Island DFS +存图
All of us love treasures, right? That's why young Vasya is heading for a Treasure Island. Treasure I ...
- cwyth(自动核销代码)
财务一体化系统,自动核销大数据代码: import pymysql import random import time #指定数据库地址.用户.密码.端口,使用connect()方法声明一个Mysql ...
- java第八周课后作业
1.系统小练习 package homework; import java.util.Random; import java.util.Scanner; public class Menu { pub ...
- SQL Server 之T-SQL基本语句 (1)
花了一天的时间看完了一本<SQL必知必会>,举个范例,来总结一下零碎的知识点.一般关于数据库操作的项目都会涉及到数据库的基本查询语句.在这里面就主要讲解一些基本常用的sql使用方法. 注: ...
- Java 多线程 -- lambda 表达式推导
jdk 8 开始 java 引入了lambda 表达式. lambda适用场景: 1.接口或父类 2.接口或父类只有一个方法 我们从多线程写法来推导一下: 1.外部类写法: package com.x ...
- JZ2440 linux-3.4.2内核启动报错:Verifying Checksum ... Bad Data CRC
使用的uboot版本是1.1.6,是打过u-boot-1.1.6_jz2440.patch的: kernel使用的版本是3.4.2, 也是打过linux-3.4.2_camera_jz2440.pat ...
- CSS中“~”(波浪号)、“,”(逗号)、“+”(加号)、“>”(大于号)、“ ”(空格)详解
“~”:$('pre ~ brother')表示获取pre节点的后面的所有兄弟节点,相当于nextAll()方法: “+”:$('pre + nextbrother')表示获得pre节点的下一个兄弟节 ...
- 我个人常用的git命令
在还没有习惯用命令行之前,我建议用一下sourcetree这个软件熟悉一下流程. 使用 git clone 拷贝一个 Git 仓库到本地:git clone url 添加所有的文件到缓存区: git ...
- [Qt] QlineEdit 限制输入,例如只能输入整数
要注意validor的作用域,如果超出作用域,则会无效.例如下面的代码,在UI的类的构造函数里.所以要new一个validtor. QIntValidator *intValidator = new ...
- 第 3 篇:实现博客首页文章列表 API
作者:HelloGitHub-追梦人物 文中所涉及的示例代码,已同步更新到 HelloGitHub-Team 仓库 此前在讨论基于模板引擎的开发方式和 django-rest-framework 开发 ...