目录

  • 5.2 最大公约数与最小公倍数
    • 问题 A: Least Common Multiple
    • 小结
  • 5.3 分数的四则运算
    • 问题 A: 分数矩阵
    • 小结
  • 5.4 素数
    • 问题 A: 素数
    • 问题 B: Prime Number
    • 问题 C: Goldbach's Conjecture
    • 小结

5.2 最大公约数与最小公倍数

Codeup Contest ID:100000589

问题 A: Least Common Multiple

题目描述
The least common multiple (LCM) of a set of positive integers is the smallest positive integer which is divisible by all the numbers in the set. For example, the LCM of 5, 7 and 15 is 105.
输入
Input will consist of multiple problem instances. The first line of the input will contain a single integer indicating the number of problem instances. Each instance will consist of a single line of the form m n1 n2 n3 … nm where m is the number of integers in the set and n1 … nm are the integers. All integers will be positive and lie within the range of a 32-bit integer.
输出
For each problem instance, output a single line containing the corresponding LCM. All results will lie in the range of a 32-bit integer.
样例输入

2
2 3 5
3 4 6 12

样例输出

15
12

思路
这题是计算多个数的最小公倍数,首先当然要明白多个数的最小公倍数怎么算,以三个数为例,先计算前两个数的最小公倍数,再计算前两个数的最小公倍数和第三个数的最大公约数,再通过公式计算出新的最小公倍数就是答案了。
另外,当m=1的时候,输出本身即可。
代码

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<time.h>
#include<algorithm>
using namespace std;
int gcd(int a, int b){//求最大公约数 if(b==0) return a;else return gcd(b, a%b);
}
int main(){int n;while(scanf("%d", &n) != EOF){while(n--){int m, x, y;scanf("%d", &m);if(m==1){int tmp;scanf("%d", &tmp);printf("%d\n", tmp);    }else{scanf("%d", &x);scanf("%d", &y);int d = gcd(x, y);int temp = (x/d)*y;//先计算前两个数的最小公倍数 for(int i=2;i<m;i++){int z;scanf("%d", &z);d = gcd(temp, z);//把最小公倍数当成一个因子,计算和下一个数的最大公约数temp = (temp/d)*z;//再根据公式算出新的最小公倍数 }printf("%d\n", temp);  }}}
}

小结

这一类的题目记住辗转相除法的函数基本上也都能解决了,主要是弄清楚三个数及以上的最大公约数、最小公倍数怎么求(先求前两个数的最大公约数/最小公倍数,再把它作为新的数和下一个数继续运算求最大公约数/最小公倍数)。

5.3 分数的四则运算

Codeup Contest ID:100000590

问题 A: 分数矩阵

题目描述
我们定义如下矩阵:
1/1 1/2 1/3
1/2 1/1 1/2
1/3 1/2 1/1
矩阵对角线上的元素始终是1/1,对角线两边分数的分母逐个递增。
请求出这个矩阵的总和。
输入
输入包含多组测试数据。每行给定整数N(N<50000),表示矩阵为N*N。当N=0时,输入结束。
输出
输出答案,结果保留2位小数。
样例输入

1
2
3
4
0

样例输出

1.00
3.00
5.67
8.83

思路
这题有三个坑:
①不能把这个矩阵定义成二维数组,50000×50000编译器都不会让你通过;
②不能按照题目意思一行一行算,这样肯定会时间超限(比如先用for循环遍历每一行,再用for循环遍历每一行的每一个元素,那时间复杂度可是O(N^2));
③不要被《算法笔记》上的定义分数结构体给误导了。
我就是一开始定义了分数,并且写了个分数加法的函数(没写约分),结果发现一直是答案错误50,怎么都过不了,后来单步调试了一下才发现当N=170左右的时候吧,因为分数加法的分母是相乘的,所以最后加出来分数的分母会巨大无比,直到溢出为0,最后答案就输出-1.#J(这是除0的输出),可能写了约分函数不会出现这种情况(我没去试),于是干脆就全部用double型来表示了,最后终于正确100了T T。

[这还只是第9个元素之和的时候,sum.down(和的分母)已经巨大无比了]
好了那么这题的思路很简单,聪明的我们当然不能被题目所迷惑,什么对角线两边分数的分母逐个递增,这都是骗你的。
你把矩阵写完,沿着对角线劈开,很容易就发现规律了。比如题目给的3×3矩阵,那半个矩阵(沿着对角线劈开的那半个)中的元素就是1个1/3,2个1/2,3个1/1,同理,N×N的矩阵的话,半个矩阵就是1个1/N,2个1/(N-1),…,N个1/1,于是只要写一个for循环把这些元素全部加起来即可,最后的结果乘2减N就行了(因为乘2的话会算两遍对角线,而对角线上的和正好是N,所以要减去一个N)。
代码

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<time.h>
#include<algorithm>
using namespace std;
int main(){int N;while(scanf("%d", &N) != EOF){if(N==0) break;double result = 0;if(N==1) result = 1;else{double sum = 0;for(int i=1, j=N;i<=N, j>=1;i++, j--) sum += i*(1.0/j);result = 2*sum-N;}printf("%.2f\n", result);}
}

小结

分数的四则运算大家肯定都知道,如果题目硬性要求输出分数类的格式的话,还是要定义一个分数的结构体去做,而且最好也要把约分的函数也写上,不然很容易就超数据类型的范围了(比如上一题),但是如果题目只是要求用分数的形式让你计算一些东西,其实也完全可以不用定义分数结构体,直接找规律就能得出答案了(比如上一题)。

5.4 素数

Codeup Contest ID:100000591

问题 A: 素数

题目描述
输入一个整数n(2<=n<=10000),要求输出所有从1到这个整数之间(不包括1和这个整数)个位为1的素数,如果没有则输出-1。
输入
输入有多组数据。
每组一行,输入n。
输出
输出所有从1到这个整数之间(不包括1和这个整数)个位为1的素数(素数之间用空格隔开,最后一个素数后面没有空格),如果没有则输出-1。
样例输入

70

样例输出

11 31 41 61

思路
这题花了很久很久很久的时间,主要是codeup答案错误50不知道错哪了……
思路很简单,用筛法也好,用普通的选素数方法也好,把范围内的素数挑出来,然后再根据题意再把个位为1的素数选出来,就是题目要求的答案了。
我这里用了埃氏筛法来做,一开始的算法是根据输入的整数n在[2,n-1]的范围内筛选素数,然后再挑选个位为1的数,牛客网一遍AC过,codeup死活过不了。
后来对比了网上的AC代码,把算法改成了在输入n之前预处理好maxn范围内的所有素数,再从素数表中挑选个位为1的数,codeup才AC(心累┓(;´_`)┏)。
如果可以的话请各位大佬告诉我原算法是哪儿没考虑到(跪求)。
代码

/原算法(在输入n之后处理[2,n-1]之内的素数,牛客网AC,但是codeup答案错误50)/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<time.h>
#include<algorithm>
using namespace std;
const int maxn = 10001;
bool p[maxn]={0};
int prime[maxn], pNum = 0;
bool judge(int a){char temp[6]={0};sprintf(temp, "%d", a);if(temp[strlen(temp)-1]=='1') return true;//末尾是1,返回true else return false;//否则返回false
}
int main(){int n;while(scanf("%d", &n) != EOF){for(int i=2;i<n;i++){if(p[i]==false){//埃氏筛法prime[pNum++] = i;for(int j=i+i;j<n;j+=i) p[j] = true;}}int cnt = 0;for(int i=0;i<pNum;i++){//此时的prime里是2~n-1之间的所有素数 if(judge(prime[i])==true){//再筛选末尾是1的数 cnt++;if(cnt==1) printf("%d", prime[i]);else printf(" %d", prime[i]);}}if(cnt==0) printf("-1\n");else printf("\n");memset(prime, 0, sizeof(prime));memset(p, 0, sizeof(p));}return 0;
}
/预处理算法(在输入n之前把maxn内的所有素数全部打成素数表,牛客网&&codeup AC)/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<time.h>
#include<algorithm>
using namespace std;
const int maxn = 10001;
bool p[maxn]={0};
int prime[maxn]={0}, pNum = 0;
bool judge(int a){char temp[6]={0};sprintf(temp, "%d", a);if(temp[strlen(temp)-1]=='1') return true;//末尾是1,返回true else return false;//否则返回false
}
int main(){for(int i=2;i<maxn;i++){if(p[i]==false){//埃氏筛法预处理出maxn内的所有素数 prime[pNum++] = i;for(int j=i+i;j<maxn;j+=i) p[j] = true;}}int n;while(scanf("%d", &n) != EOF){int cnt = 0;//记录满足题意素数的个数 for(int i=0;i<pNum;i++){//在素数表中挑 if(prime[i]<n&&judge(prime[i])==true){//如果小于n并且个位数是1 cnt++;if(cnt==1) printf("%d", prime[i]);//如果是第一个素数,直接输出 else printf(" %d", prime[i]);//如果不是,先输出空格 }}if(cnt==0) printf("-1\n");else printf("\n");}return 0;
}

问题 B: Prime Number

题目描述
Output the k-th prime number.
输入
k≤10000
输出
The k-th prime number.
样例输入

10
50

样例输出

29
229

思路
用筛法预处理出所有素数,然后根据题目输入直接查找对应的素数即可,这里要注意存储的素数表下标是从0开始的,因此,第k个素数对应的下标应该是k-1,而且这里的k最大能到10000(也就是说要保证有第10000个素数的存在,所以maxn要开大一点,我试了maxn=10万是不够的,开到100万就够了)。
代码

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<time.h>
#include<algorithm>
using namespace std;
const int maxn = 1000000;
bool p[maxn]={0};
int prime[maxn]={0}, pNum = 0;
int main(){for(int i=2;i<maxn;i++){if(p[i]==false){prime[pNum++] = i;for(int j=i+i;j<maxn;j+=i) p[j] = true;}}int k;while(scanf("%d", &k) != EOF){printf("%d\n", prime[k-1]);//因为prime的下标从0开始,所以第k个素数对应的下标应该是k-1 }return 0;
}

问题 C: Goldbach’s Conjecture

题目描述
Goldbach’s Conjecture: For any even number n greater than or equal to 4, there exists at least one pair of prime numbers p1 and p2 such that n = p1 + p2.
This conjecture has not been proved nor refused yet. No one is sure whether this conjecture actually holds. However, one can find such a pair of prime numbers, if any, for a given even number. The problem here is to write a program that reports the number of all the pairs of prime numbers satisfying the condition in the conjecture for a given even number.
A sequence of even numbers is given as input. Corresponding to each number, the program should output the number of pairs mentioned above. Notice that we are interested in the number of essentially different pairs and therefore you should not count (p1, p2) and (p2, p1) separately as two different pairs.
输入
An integer is given in each input line. You may assume that each integer is even, and is greater than or equal to 4 and less than 215. The end of the input is indicated by a number 0.
输出
Each output line should contain an integer number. No other characters should appear in the output.
样例输入

4
10
16
0

样例输出

1
2
2

思路
这题的题意大致是给你一个数,然后让你输出有几组两个素数相加能得到该数的方案。
我的思路很简单,先预处理好素数表(其实主要是为了得到散列表p),然后从2到n/2开始遍历(因为p1+p2和p2+p1算一种方案,所以只需要遍历一半),如果p[i]和p[n-i]都属于素数,那么方案数加1,最后直接输出方案数即可。
代码

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<time.h>
#include<algorithm>
using namespace std;
const int maxn = 40000;
bool p[maxn]={0};
int prime[maxn]={0}, pNum = 0;
int main(){for(int i=2;i<maxn;i++){if(p[i]==false){prime[pNum++] = i;for(int j=i+i;j<maxn;j+=i) p[j] = true;}}int n;while(scanf("%d", &n) != EOF){if(n==0) break;int cnt = 0;for(int i=2;i<=n/2;i++){//只遍历一半,因为(p1, p2)和(p2, p1)只算一种方案 if(p[i]==false&&p[n-i]==false) cnt++;//如果两者都未被筛去(说明都是素数),则方案数加1 }printf("%d\n", cnt);}return 0;
}

小结

素数的题目也是比较简单的,先把素数表用筛法预处理之后,基本上所有问题都能迎刃而解。最重要的一点是做的时候要细心一些,不然有些测试点一直卡着也会挺恼人的。

《算法笔记》学习日记——5.2 最大公约数与最小公倍数5.3 分数的四则运算5.4 素数相关推荐

  1. 算法笔记学习PAT甲级解题记录

    算法笔记学习记录 2019.06.26 float&&double 推荐全部使用double,注意区分scanf("%lf",&double1);与prin ...

  2. 三种算法求两个正整数的最大公约数和最小公倍数;求三个数的最大公约数和最小公倍数

    第二次作业 题目:求两个正整数的最大公约数和最小公倍数. 基本要求:1.程序风格良好(使用自定义注释模板),两种以上算法解决最大公约数问题,提供友好的输入输出. 提高要求:1.三种以上算法解决两个正整 ...

  3. C++算法:三种方法求最大公约数和最小公倍数

    三种方法求最大公约数和最小公倍数标题 首先明确最大公约数和最小公倍数的关系,设两个数为a,b:最大公约数为c,最大公倍数为d: 则ab=cd;怎么得到的可以通过数学算式证明. 分别用暴力搜索法,辗转相 ...

  4. 算法笔记学习(3)---深度优先搜索(DFS)

    深度优先搜索(DFS) 设想我们现在身处一个巨大的迷宫之中,以当前所在位置为起点,沿着一条路向前走,当碰到岔路口的时候,就选择其中一个岔道口前进.如果选择的这个岔路前方是一条死路,就退回到这个岔道口, ...

  5. 算法:求两个数的最大公约数与最小公倍数的方法

    1.计算两个整数的最大公约数方法有两种 第一种是使用<九章算术>中的更相减损术方法,"以少减多,更相减损,求其等也,以等数约之,等数约之,即除也,其所以相减者皆等数之重叠,故以等 ...

  6. 计算机视觉算法——Transformer学习笔记

    算机视觉算法--Transformer学习笔记 计算机视觉算法--Transformer学习笔记 1. Vision Transformer 1.1 网络结构 1.2 关键知识点 1.2.1 Self ...

  7. 聚类算法评价指标学习笔记

    聚类算法评价指标学习笔记 本文列举常用聚类性能度量指标,并列出相应代码与参考资料 聚类性能度量大致分两类,一类将聚类结果与某个"参考模型"(reference model)进行比较 ...

  8. 算法笔记(胡凡)学习笔记@Kaysen

    本文旨在记录算法笔记学习过程中的收获和一些知识点,部分易错知识点只针对个人而言,CCF-CSP考试冲鸭!!! Chapter 2 C/C++快速入门(易错知识点) 2.1 基本数据类型 变量定义注意区 ...

  9. 《算法笔记》学习笔记(1)

    <算法笔记>学习笔记(1) 2021/4/7号 晚上21:36开始学习 第二章 c++/c快速入门 有的时候不要在一个程序中同时使用cout 和 printf 有的时候会出现问题. 头文件 ...

最新文章

  1. 文件特殊权限及facl
  2. 19年8月 字母哥 第六章 生命周期内的拦截过滤与监听 用热点公司网不行
  3. 如何把Access转成SQL Server的方法介绍
  4. 五款程序员专用辅助编程工具
  5. Spark 和 MR 的区别: 多进程与多线程模型
  6. 60-200-070-使用-命令-MySQL慢查询日志
  7. Adobe Camera Raw v15.0.0.1264 增效工具
  8. css 网站黑白色,纯CSS代码将整个网站页面变成黑白色整站灰色
  9. 记录微信小程序web-view页面分享出去之后没有返回首页按钮,微信小程序WebView页面分享出去后没有返回首页按钮,全局使用的自定义导航【解决办法】
  10. python怎么加逗号_python – 什么是最简单的方法添加逗号到一个整数?
  11. python 列表操作
  12. 6、RH850 F1 AD转换功能和配置
  13. JAVA设计模式什么鬼(观察者)——作者:凸凹里歐
  14. echarts 3D折线图应用
  15. js——form表单验证
  16. 宅家36天咸鱼翻身入职腾讯,吊打面试官系列!
  17. 用友 畅捷通T+ DownloadProxy.aspx 任意文件读取漏洞
  18. linux中openssh服务搭建,配置OPenSSH服务器
  19. 必读| Algorand PPoS共识协议绝对核心优势在哪?PurePoS轻松速懂精华总结版
  20. 一种新的Tribonnbsp;Vitesse程序…

热门文章

  1. 惠州市城市职业学院计算机考点,2020广东乡镇惠州考区笔试考点地理位置及考场安排表...
  2. win10-gvim安装vim-airline后状态栏乱码,而且箭头显示不出来
  3. 使用EasyExcel从Excel表格读取链接地址下载文件
  4. linux服务器被植入挖矿病毒后初步解决方案
  5. 学习记录3——PMSM数学建模——simulink内数学模型搭建以及仿真
  6. CAD打碎块(网页版)
  7. ansible-playbook changed_when使用
  8. iOS-【转载】架构模式 - 简述 MVC, MVP, MVVM 和 VIPER
  9. 张氏矢量化骨骼化细化算法
  10. 详解TP-Link路由器设置(图解)