埃拉托斯特尼筛法(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动态规划的更多相关文章

  1. POJ 3126 Prime Path 素数筛,bfs

    题目: http://poj.org/problem?id=3126 困得不行了,没想到敲完一遍直接就A了,16ms,debug环节都没进行.人品啊. #include <stdio.h> ...

  2. Prime Path(POJ - 3126)【BFS+筛素数】

    Prime Path(POJ - 3126) 题目链接 算法 BFS+筛素数打表 1.题目主要就是给定你两个四位数的质数a,b,让你计算从a变到b共最小需要多少步.要求每次只能变1位,并且变1位后仍然 ...

  3. Prime Path(素数筛选+bfs)

    Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9519   Accepted: 5458 Description The m ...

  4. POJ - 3126 Prime Path 素数筛选+BFS

    Prime Path The ministers of the cabinet were quite upset by the message from the Chief of Security s ...

  5. Prime Path (poj 3126 bfs)

    Language: Default Prime Path Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 11703   Ac ...

  6. POJ 3216 Prime Path(打表+bfs)

    Prime Path Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 27132   Accepted: 14861 Desc ...

  7. Prime Path(POJ 3126 BFS)

    Prime Path Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 15325   Accepted: 8634 Descr ...

  8. [POJ268] Prime Distance(素数筛)

    /* * 二次筛素数 * POJ268----Prime Distance(数论,素数筛) */ #include<cstdio> #include<vector> using ...

  9. POJ 3126 - Prime Path - [线性筛+BFS]

    题目链接:http://poj.org/problem?id=3126 题意: 给定两个四位素数 $a,b$,要求把 $a$ 变换到 $b$.变换的过程每次只能改动一个数,要保证每次变换出来的数都是一 ...

随机推荐

  1. Java读源码之ReentrantLock(2)

    前言 本文是 ReentrantLock 源码的第二篇,第一篇主要介绍了公平锁非公平锁正常的加锁解锁流程,虽然表达能力有限不知道有没有讲清楚,本着不太监的原则,本文填补下第一篇中挖的坑. Java读源 ...

  2. Netty 中的异步编程 Future 和 Promise

    Netty 中大量 I/O 操作都是异步执行,本篇博文来聊聊 Netty 中的异步编程. Java Future 提供的异步模型 JDK 5 引入了 Future 模式.Future 接口是 Java ...

  3. D - Catch That Cow BFS

    农夫知道一头牛的位置,想要抓住它.农夫和牛都于数轴上 ,农夫起始位于点 N(0<=N<=100000) ,牛位于点 K(0<=K<=100000) .农夫有两种移动方式: 1. ...

  4. Celery实现周期任务

    这个翻译之后居然叫芹菜~~最近Django框架需要涉及到执行周期任务~~上网搜了下其实还挺多的(django_crontab:这个学习周期短,但是发现不仅麻烦还不好用啊).(apscheduler,简 ...

  5. C++11<functional>深度剖析

    自C++11以来,C++标准每3年修订一次.C++14/17都可以说是更完整的C++11:即将到来的C++20也已经特性完整了. C++11已经有好几年了,它的年龄比我接触C++的时间要长10倍不止吧 ...

  6. 详解 NIO流

    在观看本篇博文前,建议先观看本人博文 -- <详解 IO流> NIO流: 首先,本人来介绍下什么是NIO流: 概述: Java NIO ( New IO )是从 Java 1.4 版本开始 ...

  7. NCTF2019 小部分题解

    前言 礼拜五领航杯打的比较累,做不出WEB,D3CTF没用,做了NJCTF的一些题目(懒,睡觉到12点起) Misc 第一次比赛先去做misc,以前一直做WEB,以后要WEB+MISC做.礼拜六下午做 ...

  8. htaccess 一般配置

    一.Apache服务器 <IfModule mod_rewrite.c> Options +FollowSymlinks -Multiviews RewriteEngine on Rewr ...

  9. 20199326《Linux内核原理与分析》第十一周作业

    Shellsock攻击实验 实验背景 2014年9月24日,Bash中发现了一个严重漏洞shellshock,该漏洞可用于许多系统,并且既可以远程也可以在本地触发. Shellshock,又称Bash ...

  10. The new SFCB broker fails to start with a SSL-related error: Failure setting ECDH curve name (secp22

    # openssl ecparam -list_curves secp384r1 : NIST/SECG curve over a 384 bit prime field secp521r1 : NI ...