算法笔记.胡凡 第五章 数学问题
5.1 简单数学
【PAT A1069】
For any 4-digit integer except the ones with all the digits being the same, if we sort the digits in non-increasing order first, and then in non-decreasing order, a new number can be obtained by taking the second number from the first one. Repeat in this manner we will soon end up at the number 6174
-- the black hole of 4-digit numbers. This number is named Kaprekar Constant.
For example, start from 6767
, we'll get:
7766 - 6677 = 1089
9810 - 0189 = 9621
9621 - 1269 = 8352
8532 - 2358 = 6174
7641 - 1467 = 6174
... ...
Given any 4-digit number, you are supposed to illustrate the way it gets into the black hole.
Input Specification:
Each input file contains one test case which gives a positive integer N in the range (0,104).
Output Specification:
If all the 4 digits of N are the same, print in one line the equation N - N = 0000
. Else print each step of calculation in a line until 6174
comes out as the difference. All the numbers must be printed as 4-digit numbers.
Sample Input 1:
6767
结尾无空行
Sample Output 1:
7766 - 6677 = 1089
9810 - 0189 = 9621
9621 - 1269 = 8352
8532 - 2358 = 6174
结尾无空行
Sample Input 2:
2222
结尾无空行
Sample Output 2:
2222 - 2222 = 0000
结尾无空行
#include<iostream>
#include<algorithm>
using namespace std;
bool cmp(char a, char b){return a > b;}
int main(){string s;cin >> s;s.insert(0,4-s.length(),'0');do{string max = s, min = s;sort(max.begin(), max.end(), cmp);sort(min.begin(),min.end());int result = stoi(max) - stoi(min); s = to_string(result);s.insert(0,4-s.length(),'0');cout<< max <<" - "<< min <<" = "<< s << endl;} while (s != "6174" && s != "0000");return 0;
}
5.2 最大公约数与最小公倍数
最大公约数:欧几里得算法,即辗转相除法。
gcd(a, b) = gcd(b, a % b)
int gcd(int a, int b) {if (b == 0) return a;else return gcd(b, a % b);
}
int gcd(int x, int y) {int z = y;while (x % y != 0) {z = x % y;x = y;y = z;}return z;
}
最小公倍数 = a * b / 最大公约数
lcm(a, b) = a * b / gcd(a, b)
5.3 分数的四则运算
5.3.1 分数的表示和化简
1.分数的表示
struct Fraction { //分数int up, down;//分子、分母
}
三项规则:
①down为非负数。如果分数为负,那么令分子up为负即可。
②如果分数恰好为0,那么让分子为0,分母为1。
③分子和分母没有除了1以外的公约数。
2.分数的化简
①如果分母down为负数,那么令分子up和分母down都变为相反数
②如果分子up为0,那么令分母down为1。
③约分:求出分子绝对值和分母绝对值的最大公约数d,然后令分子分母同时除以d。
5.3.2 分数的四则运算
1.分数的加法
2.分数的减法
3. 分数的乘法
4. 分数的除法
5.3.3 分数的输出
①输出分数之前,需要对其进行化简。
②如果分数r分母为1,说明分数为整数,一般直接输出分子即可。
③如果分数r分子up的绝对值大于分母down,说明是假分数,此时应该按照带分数的形式输出,即整数部分为r.up / r.down,分子部分为abs(r.up) / r.down,分母为r.down。
④以上均不满足时说明分数r是真分数,按照原样输出即可。
为了防止分数的乘法或者除法超出int型表示范围,因此分子和分母应该使用long long型来存储。
5.4 素数
5.4.1 素数的判断
#include<math.h>
bool isPrime(int n) {if (n <= 1) return false;int sqr = (int) sqrt(1.0 * n);for (int i = 2; i <= sqr; i ++) {if (n % i == 0) return false;}return true;
}
5.4.2 素数表的获取
const int maxn = 100;//表长
int prime[maxn], pNum = 0;
bool p[maxn] = {0}; //p[i]为true说明i是素数
void Find_Prime() {for (int i = 1; i < maxn; i++) {if(isPrime(i) == true) {prime[pNum++] = i;p[i] = true;}}
}
5.4.3 素数筛法
依次类推。
const int maxn = 100;
int prime[maxn], pNum = 0;
bool p[maxn] = {0};
void Find_Prime() {for (int i = 2; i < maxn; i++) {//不能写成<=if (p[i] == false) {//i是素数prime[pNum++] = i;for (int j = i + 1; j < maxn; j +=i) {//筛去所有i的倍数p[j] = true;}}}
}
【PAT B1013】数素数
令 Pi 表示第 i 个素数。现任给两个正整数 M≤N≤104,请输出 PM 到 PN 的所有素数。
输入格式:
输入在一行中给出 M 和 N,其间以空格分隔。
输出格式:
输出从 PM 到 PN 的所有素数,每 10 个数字占 1 行,其间以空格分隔,但行末不得有多余空格。
输入样例:
5 27
结尾无空行
输出样例:
11 13 17 19 23 29 31 37 41 43
47 53 59 61 67 71 73 79 83 89
97 101 103
结尾无空行
#include <iostream>
#include <vector>
using namespace std;
bool isprime(int a) {for (int i = 2; i * i <= a; i++)if(a % i == 0) return false;return true;
}
int main() {int M, N, num = 2, cnt = 0;cin >> M >> N;vector<int> v;while (cnt < N) {if (isprime(num)) {cnt++;if (cnt >= M) v.push_back(num);}num++;}cnt = 0;for (int i = 0; i < v.size(); i++) {cnt++;if (cnt % 10 != 1) printf(" ");printf("%d", v[i]);if (cnt % 10 == 0) printf("\n");}return 0;
5.5 质因子分解
质因子分解是指将一个正整数n写成一个或者多个质数的乘积的形式。
定义一个结构体factor,用来存放质因子及其个数,如下所示:
struct factor {int x, cnt;
} fac[10];
//对于180来说,fac数组如下所示:180 = 2 * 2 * 3 * 3 * 5
fac[0].x = 2
fac[0].cnt = 2fac[1].x = 3
fac[1].cnt = 2fac[2].x = 5
fac[2].cnt = 1
对于一个正整数n来说,如果它存在[2,n]范围内的质因子,要么这些质因子全部小于sqrt(n),要么只存在一个大于sqrt(n)的质因子,其余质因子都小于等于sqrt(n)。
思路:
①枚举1~sqrt(n)内的所有质因子p,判断p是否是n的因子。如果是,则给fac数组增加质因子p,并初始化其个数为0。然后,只要p还是n的因子,就让n不断除以p,每次操作令p的个数加1,直到p不再是n的因子为止。如果p不是n的质因子,直接跳过。
②如果在上面的步骤结束后,n仍然大于1,说明n有且仅有一个大于sqrt(n)的质因子,这时只需要把这个质因子加入到fac数组,并令其个数为1。
if (n % prime[i] == 0) {fac[num].x = prime[i];fac[num].cnt = 0;while (n % prime[i] == 0) {fac[num].cnt++;n /= prime[i];}num ++;
}
if(n != 1) {fac[num].x = n;fac[num].cnt = 1;
}
【PAT A1059】
Given any positive integer N, you are supposed to find all of its prime factors, and write them in the format N = p1k1×p2k2×⋯×pmkm.
Input Specification:
Each input file contains one test case which gives a positive integer N in the range of long int.
Output Specification:
Factor N in the format N =
p1^
k1*
p2^
k2*
…*
pm^
km, where pi's are prime factors of N in increasing order, and the exponent ki is the number of pi -- hence when there is only one pi, ki is 1 and must NOT be printed out.
Sample Input:
97532468
结尾无空行
Sample Output:
97532468=2^2*11*17*101*1291
结尾无空行
//例题PAT-A-1059-Prime-Factors
#include <cstdio>
#include <cmath>
#include <iostream>
using namespace std;const int maxn = 100010;
bool is_prime(int n)//判断n是否为素数
{if(n==1) return false;int sqr = (int)sqrt(1.0*n);for(int i=2;i<=sqr;i++){if(n%i==0)return false; } return true;
} int prime[maxn],pNum = 0;void Find_Prime()//求素数表
{for(int i=1;i<maxn;i++){if(is_prime(i) == true)prime[pNum++] = i;}
} struct factor
{int x,cnt;//x为质因数,cnt为其个数
}fac[10];int main()
{Find_Prime();int n,num=0;//num为n的不同的质因子个数scanf("%d",&n);
// cin>>n;if(n == 1) printf("1=1"); // cout<<"1=1";else{printf("%d=",n);// cout<<n<<"=";int sqr = (int)sqrt(1.0*n);//n的根号//枚举根号n以内的质因子for(int i=0;i<pNum && prime[i] <= sqr;i++){if(n % prime[i] == 0)//如果prime[i]是n的质因子{fac[num].x = prime[i];//记录该因子fac[num].cnt = 0;while(n % prime[i] == 0)//计算出质因子的个数{fac[num].cnt++;n /= prime[i]; } num++;//不同质因子个数加一 } if(n == 1) break;//及时退出循环节省时间 } if(n != 1)//如果无法被根号n以内的质因子除尽{fac[num].x = n;//那么一定有 一个 大于根号n的质因子fac[num++].cnt = 1; }//按格式输出结果for(int i=0;i<num;i++){if(i>0) cout<<"*";cout<<fac[i].x;if(fac[i].cnt > 1){cout<<"^"<<fac[i].cnt; } } } return 0;
}
5.6 大整数运算
对于大整数来说,一般把大整数的每一位存在数组里面,整数的高位存放在数组的高位,整数的低位存放在数组的低位。
struct bign {int d[10000];int len;bign() {memset(d, 0, sizeof(d));len = 0;}
};
在输入大整数时,一般先用字符串读入,然后把字符串另存至bign结构体中。需要注意的是逆向读入。
bign change(char str[]) {bign a;a.len = strlen(str);for (int i = 0; i < a.len; i ++) {a.d[i] = str[a.len - i - 1] - '0';}return a;
}
5.6.1 高精度加法
bign add(bign a, bign b) {bign c;int carry = 0;for (int i = 0; i < a.len || i < b.len; i ++) {int temp = a.d[i] + b.d[i] + carry;c.d[c.len++] = temp % 10;carry = temp / 10;}if (carry != 0) {c.d[c.len++] = carry;}return c;
}
5.6.2 高精度减法
bign sub(bign a, bign b) {bign c;for (int i = 0; i < a.len || i < b.len; i++) {if (a.d[i] < b.d[i]) {a.d[i+1]--;a.d[i]+= 10;}c.d[c.len++] = a.d[i] - b.d[i];}while(c.len - 1 >= 1 && c.d[c.len-1] == 0) {c.len -- ;//去除高位0,同时至少保留一位最低位} return c;
}
如果减数小于被减数,需要交换两个变量,然后输出负号,再使用sub函数。
5.6.3 高精度与低精度乘法
bign multi(bign a, int b) {bign c;int caryy = 0;for (int i = 0; i < a.len; i++) {int temp = a.d[i] * b + carry;c.d[c.len++] = temp % 10;carry = temp / 10;}while (carry != 0) {c.d[c.len++] = carry % 10;carry /= 10;}return c;
}
5.6.4 高精度与低精度除法
bign divide(bign a, int b, int& r) {bign c;c.len = a.len;for (int i = a.len - 1; i >= 0; i--) {r = r * 10 + a.d[i];if (r < b) c.d[i] = 0;else {c.d[i] = r / b;r = r % b;}}while (c.len - 1 > 1 && c.d[c.len-1] == 0) {c.len --;}return c;
}
算法笔记.胡凡 第五章 数学问题相关推荐
- 算法笔记.胡凡 第四章 算法初步
4.1 排序 4.1.1 选择排序 void selectSort(int A[], int n) {for (int i = 0; i < n; i++) {int k = i;for (in ...
- 算法笔记胡凡 第3章 入门篇
3.5进制转换 P进制的数转换为Q进制的数,分为两步: ①将P进制的数x转换为十进制数y ②将十进制数y转换为Q进制数z 除基取余法 [PAT B1022] D进制的A+B 输入两个非负 10 进制整 ...
- 算法笔记.胡凡 第11章 动态规划专题
11.1 动态规划的递归写法和递推写法 11.1.1 动态规划的递归写法 以斐波那契数列为例,递归代码为 int F(int n) {if (n == 0 || n == 1) return 1;el ...
- 算法笔记.胡凡 第6章 C++标准模板库(STL)介绍
6.1 vector常见用法详解 6.1.1.vector定义 vector<int> name; 6.1.2.vector容器元素访问 (1) 下标:v[0] (2)迭代器 vector ...
- 算法笔记.胡凡 第九章 二叉树
9.1 树与二叉树 二叉树的存储 struct node {typename data;node* lchild;node* rchild; }; 新建节点 node* newNode(int v) ...
- 算法笔记 胡凡 codeup 数列
数列 题目链接:http://codeup.cn/problem.php?cid=100000583&pid=1 思路 由于该章节用的是递归,所以就采用递归方式来写而不是动态规划 这样的重复度 ...
- 算法笔记 胡凡 codeup 吃糖果
吃糖果 题目链接:http://codeup.cn/problem.php?cid=100000583&pid=0 思路 就是简单的递归 两种方法:当n只糖果时,可以分为 吃一只糖果,剩下n- ...
- 算法笔记胡凡 7.3.4 连接各点时代码有误
在此书7.3.4中, 静态链表结点定义如下: struct Node{typename data;int next; }node[size]; 书中要将11111,22222,33333三个地方的节点 ...
- 《算法笔记--胡凡,曾磊主编》set的用法
set的用法 set 翻译为集合,是一个内部有序且不重复的容器 #include<set> using namespace std;set的定义 定义一个set : set<type ...
最新文章
- EC笔记:第4部分:19、设计class犹如设计type
- Linux dmesg命令
- Exchange2010配置实验(六)部署forefront到edge服务器
- 阿里云消息队列python_41. Python Queue 多进程的消息队列 PIPE
- python动态改变标签的颜色_PyQt4 treewidget 选择改变颜色,并设置可编辑的方法
- Juniper Space License Issue on Citrix Xen Environment
- 项目中cxf和weblogic整合时报错的问题
- leetcode —— 1004. 最大连续1的个数 III
- mysql56数据库的创建_如何在Mysql下用命令创建数据库用户方法
- 和别人老公上床后的感觉~
- 基金登记过户系统相关
- 万能账号密码使用详解,黑客常用的入门级操作
- 基于FPGA的出租车计费器的设计
- A. 旅馆顾客统计(静态成员)
- java中的耦合_Java中的耦合
- 冉宝的leetcode笔记--每日一题 8月1日
- CLIP:从自然语言监督中学习可迁移的视觉模型
- 窗体泄漏错误has leaked window android.widget
- 百度振兴计划:中国版ChatGPT“狂飙”的机遇与挑战
- 知云文献翻译打不开_还在为论文翻译烦恼吗?点进来帮您解决
热门文章
- 见过的最全的iOS面试题
- 关于apple watch(苹果表)
- 中信银行总行信息科技岗2019年校园招聘
- 崩坏35.4版本什么时候更新
- 机器学习 (三) k-近邻算法应用-约会网站匹配系统
- 【实战系列】intel 8代I5 8400+H310完美装WIN7系统
- 常见的存储虚拟化技术(HCIE云方向)
- Redis单机最大并发量
- codeforces 869E The Untended Antiquity
- c语言程序设计教程北京邮电大学出版社答案,C语言程序设计教程习题答案~主审郭浩志北京邮电大学出版社.doc...