C++高精度加法以及2023蓝桥杯备赛计划

 新手自学,结合蓝桥杯oj, leetcode, 洛谷, oj备用等网站题目,详细介绍我对这一算法的学习过程

目录

一,解释,题目和代码

1,P1601 A+B Problem(高精)

代码

二,其他相关题目

2,P1591阶乘数码

代码

3,P1045 [NOIP2003 普及组] 麦森数(未遂)

​编辑

 代码(未遂)

总结

一,解释,题目和代码

1,P1601 A+B Problem(高精)

前言:

当我们需要求两个很大的数相加,比如10^450 + 10^436阶乘和,用long long已经满足不了

这时就需要将两个数字按字符串输入,转化为整型存入数组。

存入后如何实现相加呢,这就需要数组进位了。下面将详细介绍数组进位的算法:

数组进位:

原理与小学一年级学的竖式加法类似,比如193 + 218 = ?

先加个位3 + 8 = 11,为了使数组中每个元素都为个位数(以实现后续相加),我们需要11 / 10 = 1给下一位进个1,并在本位保留11 % 10 = 1,是不是和进制转换很像呢

这就是数组进位的原理

下面请看题目和代码:

题目:

题目描述

高精度加法,相当于 a+b problem,不用考虑负数

输入格式

分两行输入,a,b <= 10^500

输出格式

输出只有一行,代表 a+b 的值

输入
1
1
输出
2

输入
1001
9099
输出
10100

代码

#include
using namespace std;

const int N = 510;
int a[N], b[N], c[N];

int main()
{
    int i;
    string str1, str2;
    cin>>str1>>str2;
    //第一步:将字符串转换成整型输入到数组中
    for(i = 0; i < str1.size(); ++i)//.size()求string类字符串长度,strlen()求字符数组字符串长度
        a[i] = str1[str1.size() - i - 1] - '0';//比如str1为158, str1[3 - 0 - 1]就是str1[2] = 8, 为最小位
    for(i = 0; i < str2.size(); ++i)//也就是将字符串最后一位输入到数组第一位
        b[i] = str2[str2.size() - i - 1] - '0';

    //第二步:高精度加法,即数组进位
    int len = max(str1.size(), str2.size());
    for(i = 0; i < len; ++i)
    {
        c[i] = c[i] + a[i] + b[i];
        c[i + 1] = c[i] / 10;//保留进位
        c[i] = c[i] % 10;//保留个位
    }

    //第三步:完善细节
    len += 1;//防止出现996 + 111 = 107而不是1107最大位漏了的情况
    if(c[len - 1] == 0)//如果c的最大位为0,说明len + 1后多进了一位0
        len -= 1;//防止出现123 + 789 = 0912多了一位0的情况

    //第四步:逆序输出数组c(也就是从大到小)
    for(i = len - 1; i >= 0; --i)
        cout<

题目来源: P1601 A+B Problem(高精) - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

代码在洛谷可Accepted,原题在网址里,需要练习的可自行提交看是否通过

下面我提供几组测试数据,上洛谷前可先行检测
 

789
1
790

996
111
1107

123
789
912

999888777666555444333222111
111222333444555666777888999
1111111111111111111111111110

二,其他相关题目

我会罗列出网址,代码,输入输出和解析

代码会是高精度加法的不同表现方法

2,P1591阶乘数码

题目

求 n! 中某个数码出现的次数

输入格式

第一行为 t (t <= 10),表示数据组数。接下来 t 行,每行一个正整数 n (n <= 1000) 和数码 a

输出格式

对于每组数据,输出一个整数,表示 n! 中 a 出现的次数

输入
2
5 2
7 0

输出
1
2

代码

#include
#include//scanf()
#include//memset(数组名, 0, sizeof(数组名))
using namespace std;

int m[10000];

int main()
{
    int i, j, t;
	cin>>t;//将输入t组数据
	int c = 0;//保留进位
    int sum = 0;//中间值, c, sum在for内初始化会累加
	for(int k = 0; k < t; ++k)//这里不要声明i, 会被下面的i干扰
    {
        memset(m,0,sizeof(m));//对数组m初始化,防止连续输入后累加
        int n, a;
        scanf("%d %d", &n, &a);//n表示n的阶乘
        m[0] = 1;
//↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓核心代码↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
        for(i = 2; i <= n; ++i)
            for(j = 0; j < 3000; ++j)
            {
                sum = c + m[j] * i;
                m[j] = sum % 10;//保留个位数
                c = sum / 10;//保留进位
            }
//↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑核心代码↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
        long long num = 0;//a出现的次数
        for(i = 3000; i >=0; --i)
            if(m[i] != 0)//数据开始出现
            {
                for(j = i; j >= 0; --j)
                    if(m[j] == a)
                        num++;
                break;//从a最后一个数输出到a[0]
            }
        cout<

输入输出

6
12 3
0
12 7
1
104 5
14
104 3
12
104 0
33
10 0
2

分析

中间还出现一个报错:invalid types ‘int[int]’ for...意思是数组名与常量名重复定义,毕竟数组习惯用a[10000]了 

耗时198ms

一开始用了1.26秒,因为22行j < 10000,多了不必要的循环,当改成j <= 3000,就405ms,开启O2优化直接198ms

题目来源P1591 阶乘数码 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

需要的可在洛谷自行练习提交

3,P1045 [NOIP2003 普及组] 麦森数(未遂)

害,突然发现这个要高精度乘法,还没学,想了两个小时没ACCEPTED

题目

C++高精度加法以及2023蓝桥杯备赛计划_第1张图片

 C++高精度加法以及2023蓝桥杯备赛计划_第2张图片

 代码(未遂)

注意,代码没过,只是我一开始的思路,等系统学完高精度加,减,乘,除,我再补充完整

#include
#include//memset()
using namespace std;

int a[100010];

int main()
{
    memset(a, 0, sizeof(a));//初始化数组是好习惯
    a[0] = 2;
    int p, i, j;//2^p
    cin>>p;
    int c = 0;//c为进位

/*↓↓↓↓↓↓↓↓↓↓↓↓↓↓核心代码↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓*/
    for(i = 1; i < p; ++i) {
        j = 0;
        while(j < 500) {
            a[j] = a[j] + ;
            if(a[j] >= 10) {
                a[j + 1] = a[j] / 10;//保留进位
                a[j] = a[j] % 10;//保留个位数
                j++;
            }
        }
    }
/*↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑核心代码↑↑↑↑↑↑↑↑↑↑↑↑↑↑*/
    for(int k = 499; k >= 1; --k) {
        cout<

这个代码没过

题目来源P1045 [NOIP2003 普及组] 麦森数 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

总结

为了2023-4月蓝桥杯A组拿个省二,我还要学习的有:

1,排序(选择,插入,冒泡,快速的手写), sort()

2,枚举(循环遍历,dfs,bfs)(暴力出奇迹

3,最大公约数,最小公倍数,素数筛

4,二分查找,差分查找,dfs剪枝优化

5,递归(dfs, 阶乘),分治(手写快排)

6,贪心算法

7,队列,栈,线性表,图

8,动态规划

实施步骤:

1,学完MOOC中C++指针,结构体链表,面向对象的内容,做3~5道编程题

2,挑拣着做下洛谷入门题单,巩固下输入输出以及基本语法

3,对照1~8,逐个击破

分配时间:

寒假每日3小时,开学后每日2小时

长路漫漫,共勉,A组省三都不好拿我觉得,本来就0基础

你可能感兴趣的:(2024蓝桥杯备赛,c++,蓝桥杯,算法)