Update

  • \(\texttt{2021.7.3}\) 经测试,本题 \(a,b\) 范围在 long long,对代码进行了修改,并修改一些笔误,更新了数据范围。
  • \(\texttt{2021.7.5}\) 应评论区要求,加上了 long (int) 的数据范围,并修改了原题中 \(a,b\) 的数据范围。
  • \(\texttt{2021.7.16}\) 去掉了数据范围中的绝对值符号,感谢 @Implicit 的提醒。另外对原文章中的一些错误进行了修改。但之后题解被无意义内容打回了,一开始决定将本题解里头涉及到的语言知识放入一个剪贴板中,并对整体编排做了较多修改,后经 WYXkk 和 XYY1411 的建议作了一些知识性方面和排版方面的修改,并重新将剪贴板的内容放在代码后面以作补充性讲解。感谢各位的建议!

Content

给定 \(a,b\),求 \(a+b\)。

数据范围:\(1\leqslant a,b\leqslant4\times10^{18}\)。

Solution & Code

本题解仅适用于 C++ 选手。

这道题可谓是 C++ 中最基础的题目之一,先上两份代码:

1

#include <cstdio>
using namespace std; int main() {
long long a, b;
scanf("%lld%lld", &a, &b);
printf("%lld", a + b);
return 0;
}

2

#include <iostream>
using namespace std; int main() {
long long a, b;
cin >> a >> b;
cout << a + b;
return 0;
}

那么这一行行语句都代表着什么呢?这两个程序如何达到相同的效果呢?接下来就对此进行详细讲解。当然,初学者如果看不懂这些东西其实也无关紧要,因为这些都将在我们今后的学习中逐渐了解。

Part 1 基础语言知识

首先我们要知道程序最开始的 #include <xx> 是什么意思,其实就是把 C++ 中的一些头文件库给包括进来,这里给几个常见的头文件库:

<cstdio> //输入/输出(这是注释)
<iostream> //输入/输出流
<string> //字符串类
<cstring> //同上
<cmath> //包含了许多实用的数学函数,例如 sin(),cos(),tan(),sqrt(),pow() 等
<algorithm> //STL 通用算法
<stack> //STL 栈容器
<queue> //STL 队列容器
<deque> //STL 双端队列容器
<map> //STL 映射容器
<vector> //STL 动态数组容器
/*
这是多行注释。
STL 可以很方便的简化我们的代码,但是常数很大,
有时运行起来很慢,所以建议知道如何手写。
这将是我们以后学习的内容,现在不知道并无大碍。
*/

对于这道基础题目,我们只需要包含 cstdio 库或者 iostream 库,因为这道题目只需要我们输出 \(a+b\) 的结果。

然后就是数据类型的问题。我们先不妨认识一些常用的数据类型。下图的这些数据类型(C++ 其他常用数据类型除外)统称为预定义类型,也就是说,这些数据类型是 C++ 已经为你准备好的。

另外,我们还将学到数组、结构体 struct 联合体 union、枚举 enum 等其他比较灵活的类型,这些数据类型统称为自定义数据类型

那我们如何选择数据类型呢?这得要从数据范围来决定。以下给出了常用数据类型在通常情况下的范围(建议去题解页面查看),对于今后做题时变量应该如何选择数据类型有很大的作用:

数据类型 范围
char \([-128,127]\) 或 \([0,255]\),在系统字节不是 8 位的情况下可以达到更大的数据范围
unsigned char \([0,255]\),在系统字节不是 8 位的情况下可以达到更大的数据范围
signed char \([-128,127]\),在系统字节不是 8 位的情况下可以达到更大的数据范围
int/long (int) 通常情况下为 \([-2147483648,2147483647]\)(或者说 \([-2^{31},2^{31}-1]\)),但 int 只保证 \([-32768,32767]\)(或者说 \([-2^{15},2^{15}-1]\))
unsigned int \([0,4294967295]\)(或者说 \([0,2^{32}-1]\))
signed int 同 int
short int 至少 \([-32768,32767]\)(或者说 \([-2^{15},2^{15}-1]\)),但可以达到更大的数据范围
unsigned short int \([0,65535]\)(或者说 \([0,2^{16}-1]\))
signed short int 同 short int
long long (int) 通常情况下为 \([-9223372036854775808,9223372036854775807]\)(或者说 \([-2^{63},2^{63}-1]\)),但在 C++11 开始才保证至少是这个数据范围
signed long long (int) 同 long long (int)
unsigned long long (int) \([0,18446744073709551615]\)(或者说 \([0,2^{64}-1]\))
float \([1.17\times 10^{-38},3.40\times 10^{38}]\)(约数,来源于 IEEE-754 标准)
double \([2.23\times 10^{-308},1.80\times 10^{308}]\)(约数,来源于 IEEE-754 标准)
long double \([3.36\times 10^{-4932},1.19\times 10^{4932}]\)(约数,一说和 double 范围相等)

关于 long double 的一些说明:long double 是一种扩展精度浮点类型,不一定映射到 IEEE-754 所强制的类型。在 x86 和 x86-64 架构上通常为 80 位 x87 浮点类型。表格中采取的 long double 的数据范围来源于这篇文章

然后就是函数了,函数有头文件库里面自带的,也有你需要在程序中自己写出来的。比如说 sin()sort() 这些就是 C++ 的头文件库里面自带的,而通常程序中有些函数需要你自己写出来。在需要自己写出来的函数中,最重要也是最必不可少的就是 main() 函数。一般在算法竞赛中,它的类型通常是 int,而且最后通常会要求你写 return 0;,具体的意义不做赘述。除了 main() 函数和头文件库里面自带的函数外,你也可以自己写一些其他的函数,达到精简代码的效果。

然后就是输入和输出了,如果你调用的是 cstdio 库的话,它里头包含的最常用的输入函数就是 scanf()

scanf() 函数返回成功读入的数据项数,读入数据时遇到了“文件结束”则返回 EOF(End of file,即文件结尾)。例如,对于这道题,我们需要读入 \(a,b\),就用 scanf("%d%d", &a, &b),其中 %dint 这个数据类型在 scanf() 函数中的格式,其它的格式还有 %f \(\rightarrow\) float%lf \(\rightarrow\) double%lld \(\rightarrow\) long long 等。另外,scanf() 函数还有一个强大的功能,就是你可以用 scanf() 按照某一个特定的格式读入数据,例如,你想要按照 hh:mm 的个数读入 \(hh\) 和 \(mm\),就可以用 scanf("%d:%d", &hh, &mm)。注意,如果是整形类型的话,变量前的 & 必不可少

为什么要加一个 & 号?这里不多做讲述,感兴趣的各位可以去看这个剪贴板

如果你调用的是 iostream 库的话,它里头包含的输入流(注意!并不是函数)是 cin。你就把输入流想象成一条河流,源源不断地输入数据就行,这里就不给出严格定义了。在 cin 中,每一个输入的数据以 >> 号连接,前面并不需要加 &

然后就是输出了,输出其实和输入很类似,所以这里仅作简略讲解。

scanf() 函数对应的是 printf() 函数,返回成功输出的数据项数。按照和 scanf() 一样的格式,同样也可以按照某个特定格式输出数据,例如 %8d 就可以讲一个整数按以 \(8\) 为宽度右对齐输出(详情请见 B2004),%02d 就可以将一个整数输出,并且如果不足两位的话会向前补前导零。例如 printf("%8d, %02d", 2, 2) 对应的输出结果就是:

        2, 02

另外如果题目要求保留一位小数或者你的输出应与答案的相对误差不超过 \(10^{-3}\) 等要求,那么我们就可以利用 printf 中的按位输出的格式 %.xlf或者 %.xf 输出(其中 x 里面是数字),例如保留一位小数就可以写成 printf("%.1lf", x);

输入流 cin 自然也就对应输出流 cout,你同样也可以将其想象成一条源源不断地输出数据的河流。但请注意,在 cout 中,每一个输出的数据以 << 连接!!!除了这个地方和 cin 不同之外,其他的都和 cin 并无差异。

那么 cout 是否也可以做到按位输出或者按某个特定宽度右对齐输出呢?答案是肯定的,但由于版面原因,这里并不做介绍,感兴趣的各位可以直接上网查询。

Part 2 本题你需要了解的一些东西

对于这道题目来说,\(1\leqslant a,b\leqslant4\times10^{18}\),因此我们用 long long/signed long long 数据类型。因为在算法竞赛中 long long 常用些,所以这里的代码也用的是 long long 这个数据类型。

接下来就是如何表示 \(a+b\) 了,这里就要讲到 C++ 中的数字运算符。首先就是最基本的加减乘除,它在 C++ 中分别表示为 +-*/,但请注意,/ 在 C++ 中的定义并不完全等同于我们平常的四则运算中的除法,如果两边都是整型变量,在 C++ 中,/ 默认为整除。那么有没有办法可以让它变成我们平常的除法呢?答案是肯定的,让 / 两边中的一个或者两个数变成浮点型变量(\(\texttt{float}\)、\(\texttt{double}\)、\(\texttt{long double}\) 等),就可以让 / 的结果变为实际结果而不是整除后的结果了。例如,\(\texttt{5/6}\) 在 C++ 中的结果是 \(0\),但如果你将其变成 \(\texttt{5.0/6}\) 或 \(\texttt{5/6.0}\) 或 \(\texttt{5.0/6.0}\),那么 C++ 就会输出其正确的结果 \(\texttt{0.8333\dots}\)(具体输出多少位取决于题目具体要求)。那么它的运算顺序是怎样的呢?如果仅限于加减乘除的话,它的运算顺序和平常的四则运算顺序是一样的:先乘除后加减,有括号先算括号里面的算式。只不过 C++ 里面提供运算的符号仅为小括号 () 罢了。

那么我们对于程序做了深入的剖析,想必大家都已经领会到 C++ 的语言魅力了。

Notice

本文章引用了一些网络上的内容,由于作者能力有限,可能仍不免有诸多错误,欢迎各位在评论区指出,作者将定期订正这些错误。

同时,如果您认为这篇文章侵犯了你的著作权,请及时和作者联系换下。

另外,这篇文章期间也经过了一些不小的修改,感谢 WYXkk、XYY1411、Implicit 等各路神仙对这篇文章提出的宝贵的修改建议,才使得这篇文章经过不断完善变得更加充实和严谨!

祝各位的信息之路愉快而又充实!

LuoguB2001 入门测试题目 题解的更多相关文章

  1. ZROI 部分题目题解

    ZROI 部分题目题解 335 首先发现一个性质: 对于最短的边而言,所有点的路径如果经过了这条边,那么路径的权值就是这条边的边权(废话) 那么我们把最短的边拎出来,可以发现,博物馆确定时,每个点按照 ...

  2. PTA|团体程序设计天梯赛-练习题目题解锦集(C/C++)(持续更新中……)

    PTA|团体程序设计天梯赛-练习题目题解锦集(持续更新中) 实现语言:C/C++:      欢迎各位看官交流讨论.指导题解错误:或者分享更快的方法!! 题目链接:https://pintia.cn/ ...

  3. 一套很有意思的C语言测试题目

    网络上逛博客,发现了一套很有意思的测试题目: https://kobes.ca/ 大家有兴趣可以做一下,考一些关于C语言使用的细节: 中文翻译参考: https://www.cnblogs.com/l ...

  4. 软件测试入门——测试模型(V型 W型 H型)

    软件测试工程师称为“QA”,质量保证者——这是入门的第一点要学习的. 首先看基本的测试模型 1.“V”型 特点:[活动串行]这是一种古老的瀑布模型,反映了实际和测试之间的关系. 局限:仅仅把测试过程作 ...

  5. chd校内选拔赛题目+题解

    题目链接   A. Currency System in Geraldion 有1时,所有大于等于1的数都可由1组成.没有1时,最小不幸的数就是1. #include<iostream> ...

  6. Tarjan & LCA 套题题目题解

    刷题之前来几套LCA的末班 对于题目 HDU 2586 How far away 2份在线模板第一份倍增,倍增还是比较好理解的 #include <map> #include <se ...

  7. 《Cracking the Coding Interview》——第12章:测试——题目6

    2014-04-25 00:53 题目:你要如何测试一个分布式银行系统的ATM机? 解法:ATM是Automatic Teller Machine,取钱的.我想了半天,没找到什么很清晰的思路,也许是因 ...

  8. 《Cracking the Coding Interview》——第12章:测试——题目5·

    2014-04-25 00:41 题目:怎么测试一支笔?(Pen?您老说的是钢笔?) 解法:这种简约而不简单的题目,实在是面试官最喜欢,面试者最头疼的类型了.面试官可以只花三秒,以一种灰常高贵冷艳的语 ...

  9. 《Cracking the Coding Interview》——第12章:测试——题目4

    2014-04-25 00:35 题目:没有专门的测试工具,你要如何对一个网页进行压力测试? 解法:拼手速,拼电脑数量呗.快捷键+复制粘贴网址,狂搞一番.话说回来,有脚本语言的情况下,直接写个脚本来模 ...

随机推荐

  1. Hibernate数据校验简介

    我们在业务中经常会遇到参数校验问题,比如前端参数校验.Kafka消息参数校验等,如果业务逻辑比较复杂,各种实体比较多的时候,我们通过代码对这些数据一一校验,会出现大量的重复代码以及和主要业务无关的逻辑 ...

  2. HTML四种定位-绝对定位

    绝对定位 1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset=&q ...

  3. Atcoder Grand Contest 001 D - Arrays and Palindrome(构造)

    Atcoder 题面传送门 洛谷题面传送门 又是道思维题,又是道把我搞自闭的题. 首先考虑对于固定的 \(a_1,a_2,\dots,a_n;b_1,b_2,\dots,b_m\) 怎样判定是否合法, ...

  4. Atcoder Grand Contest 001 F - Wide Swap(拓扑排序)

    Atcoder 题面传送门 & 洛谷题面传送门 咦?鸽子 tzc 来补题解了?奇迹奇迹( 首先考虑什么样的排列可以得到.我们考虑 \(p\) 的逆排列 \(q\),那么每次操作的过程从逆排列的 ...

  5. Codeforces 1264F - Beautiful Fibonacci Problem(猜结论+找性质)

    Codeforces 题面传送门 & 洛谷题面传送门 一道名副其实(beautiful)的结论题. 首先看到这道设问方式我们可以很自然地想到套用斐波那契数列的恒等式,注意到这里涉及到 \(F_ ...

  6. 【转】群体研究套路:开心果denovo+重测序+转录组+群体进化+选择位点

    转自公众号Eric生信小班.学习群体遗传套路 中科院昆明动物园吴东东研究团队联合国外研究团队2019年在Genome Biology发表题为Whole genomes and transcriptom ...

  7. Python异步IO之select

    1. select模块的基本使用(以socket为例) 1 # -*- coding:utf-8 -*- 2 # Author:Wong Du 3 4 import select 5 import s ...

  8. MPI 学习笔记

    目录 MPI学习笔记 MPI准备 概述 前置知识补充 环境部署 1.修改IP及主机名 2.关闭防火墙 3.实现免密码SSH登录 4.配置MPI运行环境 5.测试 程序的执行 编译语句 运行语句 MPI ...

  9. R语言学习记录(二)

    4.对象改值 4.1.就地改值 比如: vec <- c(0,0,0,0,0,0,0) vec[1]<-100 #vec向量的第一个值就变为100 ####对于数据框的改值的方法,如下面的 ...

  10. RB-Tree深度探索

    关联式容器就是通过key值来寻找value,这个和数据库很相像,为了提升查找效率,因此关联式容器底层大多数用红黑树或哈希表来实现. 红黑树是高度平衡的二叉树,它也被称为平衡二元搜索树. 如上所示,正常 ...