算法笔记.胡凡 第五章 数学问题

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 = 2

fac[1].x = 3
fac[1].cnt = 2

fac[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 = p1​k1​×p2​k2​×⋯×pm​km​.

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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
东南亚位于我国倡导推进的“一带一路”海陆交汇地带,作为当今全球发展最为迅速的地区之一,近年来区域内生产总值实现了显著且稳定的增长。根据东盟主要经济体公布的最新数据,印度尼西亚2023年国内生产总值(GDP)增长5.05%;越南2023年经济增长5.05%;马来西亚2023年经济增速为3.7%;泰国2023年经济增长1.9%;新加坡2023年经济增长1.1%;柬埔寨2023年经济增速预计为5.6%。 东盟国家在“一带一路”沿线国家中的总体GDP经济规模、贸易总额与国外直接投资均为最大,因此有着举足轻重的地位和作用。当前,东盟与中国已互相成为双方最大的交易伙伴。中国-东盟贸易总额已从2013年的443亿元增长至 2023年合计超逾6.4万亿元,占中国外贸总值的15.4%。在过去20余年中,东盟国家不断在全球多变的格局里面临挑战并寻求机遇。2023东盟国家主要经济体受到国内消费、国外投资、货币政策、旅游业复苏、和大宗商品出口价企稳等方面的提振,经济显现出稳步增长态势和强韧性的潜能。 本调研报告旨在深度挖掘东南亚市场的增长潜力与发展机会,分析东南亚市场竞争态势、销售模式、客户偏好、整体市场营商环境,为国内企业出海开展业务提供客观参考意见。 本文核心内容: 市场空间:全球行业市场空间、东南亚市场发展空间。 竞争态势:全球份额,东南亚市场企业份额。 销售模式:东南亚市场销售模式、本地代理商 客户情况:东南亚本地客户及偏好分析 营商环境:东南亚营商环境分析 本文纳入的企业包括国外及印尼本土企业,以及相关上下游企业等,部分名单 QYResearch是全球知名的大型咨询公司,行业涵盖各高科技行业产业链细分市场,横跨如半导体产业链(半导体设备及零部件、半导体材料、集成电路、制造、封测、分立器件、传感器、光电器件)、光伏产业链(设备、硅料/硅片、电池片、组件、辅料支架、逆变器、电站终端)、新能源汽车产业链(动力电池及材料、电驱电控、汽车半导体/电子、整车、充电桩)、通信产业链(通信系统设备、终端设备、电子元器件、射频前端、光模块、4G/5G/6G、宽带、IoT、数字经济、AI)、先进材料产业链(金属材料、高分子材料、陶瓷材料、纳米材料等)、机械制造产业链(数控机床、工程机械、电气机械、3C自动化、工业机器人、激光、工控、无人机)、食品药品、医疗器械、农业等。邮箱:market@qyresearch.com
### 回答1: 《算法笔记》是一本由胡凡撰写的计算机科学书籍,该书主要介绍了一些常见的算法和数据结构,并且给出了相应的代码实现。 胡凡的代码非常简洁清晰,注释详细。他的代码实现旨在提供读者一个易于理解和实现的参考模板,以提高读者对算法和数据结构的理解和应用能力。 《算法笔记》的代码实现涵盖了众多经典的算法和数据结构,如排序算法、图算法、动态规划等。通过学习这些代码,读者可以更好地理解算法的思想和设计方法。 此外,胡凡的代码实现还包括一些实际应用的案例,这使得读者能够将所学的算法和数据结构应用到自己的项目中。通过实际的案例,读者可以进一步加深对算法的认识,并学会如何将算法应用到实际问题中解决。 总的来说,胡凡的代码实现非常有参考价值,对于算法和数据结构的学习和应用都具有很大的帮助。他的代码简洁清晰,容易理解和实现,是学习算法的一本不可多得的好书。 ### 回答2: 《算法笔记》是由胡凡编写的一本关于算法的学习资料。这本书主要介绍了算法的基本概念、常见的算法思想和常用的算法模板。胡凡是一位算法领域的专家,他将自己多年的学习和研究经验融入其中,旨在帮助读者更好地理解算法的本质和应用。 在《算法笔记》中,胡凡通过清晰明确的语言和丰富多样的示例,向读者介绍了常见的排序算法、查找算法、图算法等等。同时,他还特别强调了算法的时间复杂度和空间复杂度分析的重要性,以及如何通过优化算法提升程序的效率。这对于想要提高编程水平的读者来说是非常有价值的。 胡凡的代码也是《算法笔记》的重要内容之一。他以Python为主要编程语言,用简洁而易懂的代码实现了书中介绍的各种算法。这些代码通常具有较高的复用性和可读性,既能够帮助读者理解算法的具体实现逻辑,也可以作为实际项目中的参考代码。 总之,《算法笔记》是一本很好的算法学习资料,它通过详细的讲解和清晰的代码示例,帮助读者建立了对算法的深入理解。无论是初学者还是有一定经验的程序员,都可以从中获得很多有价值的知识和技巧。通过不断地学习和实践,读者可以在编程中灵活应用这些算法,提高自己的编程水平。 ### 回答3: 《算法笔记》是一本非常经典的算法教材,由胡凡和曾磊合著。书中详细介绍了各种常见的算法及其实现方法,对算法的思想和原理进行了深入剖析,为读者提供了全面的学习指南。 在《算法笔记》中,作者以清晰的逻辑和简洁的代码,让读者了解算法设计的基本原则和常见的解题思路。胡凡的代码是书中的重要组成部分,通过实例和案例,读者可以深入理解算法的实际应用,同时也能掌握用代码实现各种算法的技巧。 胡凡的代码非常精炼和高效,他在编写代码时注重算法的时间和空间复杂度,以求得最优解。无论是经典算法的实现,如排序算法、贪心算法,还是动态规划、图算法等高级算法胡凡的代码都能给读者带来很多启发和思考。 此外,胡凡的代码还注重代码复用和模块化设计,他通过定义适当的数据结构和函数,使得代码结构清晰,易于理解和修改。这有助于读者在实际项目中灵活运用算法,并提高编码的质量和效率。 总之,《算法笔记》中胡凡的代码是一道亮丽的风景线,它不仅仅是学习算法的工具,更是一本智慧的结晶。通过学习胡凡的代码,读者可以提升自己的算法水平,拓宽思维的广度和深度,从而在日后的工作和学习中取得更好的成果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值