C++洛谷基础练习题及解答

发布于:2025-03-17 ⋅ 阅读:(13) ⋅ 点赞:(0)

c++基础练习题

入门题

  • B2003 输出第二个整数

    #include<iostream>
    using namespace std;
    int main()  {
    	int a,b,c;//定义3个分别叫a,b,c的变量
    	cin>>a>>b>>c;//cin表示输入,本行表示输入a,b,c
    	cout<<b<<endl;//表示输出b
    	return 0;
    }
    
  • B2007 A + B 问题

    #include <iostream>
    using namespace std;
    
    int main() {
        int A, B;
        // 读取输入的整数 A 和 B
        cin >> A >> B;
        // 输出 A + B 的结果
        cout << A + B << endl;
        return 0;
    }
    
  • B2004 对齐输出

    考点:本题主要考察输出流的控制。

    头文件 <iomanip> 中提供了许多用于控制输出流的函数,在使用以下内容介绍的函数前,需要包含 <iomanip> 头文件。

    setw() 函数可以控制输出流的下一个输出内容的场宽。

    以下是一个使用的例子。

    当运行以下语句时:

    int a=114514;
    cout<<a;
    

    输出结果将为:

    114514
    

    当包含了头文件<iomanip>,并运行以下语句时:

    int a=114514;
    cout<<setw(10)<<114514;  //设置场宽为10
    

    输出结果将为:

        114514
    

    可见,当下一个输出的内容的宽度不足 setw() 函数中设置的参数时,输出流将自动在这个输出内容的前面添加字符(默认为空格)来补齐宽度。

    当下一个输出的内容超过 setw() 函数中设置的参数时,将不会产生任何效果,例如:

    int a=114514;
    cout<<setw(1)<<a;
    

    输出结果将为:

    114514
    

    需要特别注意, setw() 函数只会对下一个输出内容有效,对于多个输出内容,需要重新设置,例如:

    int a=114,b=514;
    cout<<setw(10)<<a<<" "<<b;
    

    输出结果将为:

           114 514
    

    正确的使用方法为:

    int a=114,b=514;
    cout<<setw(10)<<a<<" "setw(10)<<b;
    

    输出结果将为:

           114        514
    

    完整解题代码:

    解法1:

    #include <iostream>
    #include <iomanip>  // 引入头文件以设置输出宽度
    using namespace std;
    
    int main() {
        int a, b, c;
        // 读取三个整数 a, b, c
        cin >> a >> b >> c;
        // 输出时,每个整数占8个字符,且格式化输出
        cout << setw(8) << a << " " << setw(8) << b << " " << setw(8) << c << endl;
        return 0;
    }
    

    拓展:

    你还可以使用 setfill() 函数更改补齐宽度时使用的字符,例如

    int a=114514;
    cout<<setfill('*')<<setw(10)<<a;  //将补齐宽度时使用的字符设置为'*'
    

    输出结果将为:

    ****114514
    

    setfill() 函数将对设置之后输出流的所有内容有效,例如:

    int a=114,b=514;
    cout<<setfill('*')<<setw(10)<<a<<" "<<setw(10)<<b;
    

    输出结果将为:

    *******114 *******514
    

    又例如:

    int a=114,b=514;
    cout<<setw(10)<<a<<" "<<setfill('*')<<setw(10)<<b;
    

    输出结果将为:

           114 *******514
    

    解法2:c语言语法

    使用 printf 函数里那个右对齐的格式符就行了。

    举例:

    如果你想输出一个 long long 整数,可以这样写:printf("%lld",a);

    如果你想要右对齐,占 3 个字符宽度,可以这样写:printf("%3lld",a);

    如果你想要左对齐,在那个数字前加一个 - 即可。如:printf("%-3lld",a);

    #include<cstdio>
    using namespace std;
    
    int main(){
        long long a,b,c;
    	scanf("%lld%lld%lld",&a,&b,&c);
    	printf("%8lld %8lld %8lld",a,b,c);
    	return 0;
    }
    
  • B2008 计算 (a+b)×c 的值

    #include<iostream>
    using namespace std;
    int main(){
        int a,b,c;
        cin>>a>>b>>c;
        cout<<(a+b)*c<<endl;
    }
    
  • B2011 计算分数的浮点数值

    知识点:使用 cout<<setprecision(a)<<fixed<<b<<endl; 可以将 b 的值保留 a 位小数后输出。

    万能头文件:#include<bits/stdc++.h>

    包括一下头文件:

    #include <iostream>
    #include <cstdio>
    #include <fstream>
    #include <algorithm>
    #include <cmath>
    #include <deque>
    #include <vector>
    #include <queue>
    #include <string>
    #include <cstring>
    #include <map>
    #include <stack>
    #include <set>
    
    1. <iostream>
      这个头文件提供了输入输出流的功能。常用的对象包括:
      • cin:用于从标准输入读取数据。
      • cout:用于向标准输出打印数据。
      • cerr:用于输出错误信息(标准错误流)。
      • clog:用于输出日志信息(标准日志流)。
    2. <cstdio>
      这个头文件包含了 C 风格的输入输出函数。常用函数包括:
      • printf:格式化输出。
      • scanf:格式化输入。
      • fopen:打开文件。
      • fclose:关闭文件。
      • fprintf:向文件写入格式化数据。
    3. <fstream>
      这个头文件提供了文件流操作的功能。常用的类包括:
      • ifstream:输入文件流,用于从文件中读取数据。
      • ofstream:输出文件流,用于向文件中写入数据。
      • fstream:读写文件流,可以同时进行读写操作。
    4. <algorithm>
      这个头文件包含了一些常用的算法,如:
      • sort:排序算法。
      • find:查找元素。
      • reverse:反转容器。
      • max, min:求最大值和最小值。
    5. <cmath>
      这个头文件包含数学函数,如:
      • sqrt:求平方根。
      • pow:幂运算。
      • sin, cos, tan:三角函数。
      • log:对数函数。
    6. <deque>
      这个头文件提供双端队列的功能。deque 是一种可以在两端高效插入和删除元素的数据结构。
    7. <vector>
      这个头文件提供了向量(动态数组)的功能。vector 是一种可以动态扩展的数组容器,支持随机访问。
    8. <queue>
      这个头文件提供队列的功能。常用的类包括:
      • queue:先进先出(FIFO)的队列。
      • priority_queue:优先队列,按照优先级进行排序。
    9. <string>
      这个头文件提供字符串的功能。string 是 C++ 标准库中的字符串类,支持动态字符串处理。
    10. <cstring>
      这个头文件提供了 C 风格字符串的处理函数。常用的函数包括:
      • strlen:求字符串的长度。
      • strcmp:比较两个字符串。
      • strcpy:复制字符串。
    11. <map>
      这个头文件提供了映射(字典)功能。map 是一种基于红黑树实现的有序关联容器,能够根据键快速查找对应的值。
    12. <stack>
      这个头文件提供栈(后进先出)的功能。stack 是一种容器适配器,只支持从栈顶进行操作(pushpop)。
    13. <set>
      这个头文件提供了集合的功能。set 是一种基于红黑树实现的有序容器,支持自动去重和排序。

    解法1:

    #include<bits/stdc++.h    // #include<cstdio>
    using namespace std;
    int main()
    {
    	double a, b;//因为后面要除,所以要设为浮点数形式。 float
        cin >> a >> b;
        cout << fixed << setprecision(9) << a / b; // 保留小数点后 9 位输出  *   9 % 4 =1  9 / 4 =2
    	return 0;
    }
    

    解法2:

    #include<bits/stdc++.h>
    using namespace std;
    int main()
    {
    	double a, b;//因为后面要除,所以要设为浮点数形式。
        scanf("%lf%lf", &a, &b);
        printf("%.9lf", a / b);
    	return 0;
    }
    
  • B2012 甲流疫情死亡率

    a 表示确诊数,b 表示死亡数,则甲流死亡率为 b/a

    又因为要以百分数形式输出:

    百分数相当于将数字乘 100 输出后再加上 %

    • 要求保留三位小数,可以用到 cout<<fixed<<setprecision(x)<<a<<endl;,意思是输出 a,保留 x 位小数。
    • a,bdouble 类型储存,方便计算小数。

    解法1:

    #include <bits/stdc++.h>
    using namespace std;
    int main()
    {
        double a, b;
        cin >> a >> b;
        cout << fixed << setprecision(3) << 100.0*b / a << '%' << endl;  // 保留三位小数输出
        return 0;
    }
    

    解法2:

    #include <bits/stdc++.h>
    using namespace std;
    int main()
    {
        int a, b;
        scanf("%d%d", &a, &b);
        printf("%.3f%%", 100.0 * b / a); // %.3f 占位符保留三位小数输出
        // 输出 % 要 printf("%%"),题面中也有。
        return 0;
    }
    
  • B2013 温度表达转化

    解法1:

    #include <bits/stdc++.h>
    using namespace std;
    
    int main() {
    	double C,F;
    	cin>>F;
    	C=5*(F-32)/9.0;
    	cout<<fixed<<setprecision(5)<<C;   // 保留五位小数输出
    	return 0;
    }
    

    解法2:

    #include<bits/stdc++.h>
    using namespace std;
    int main(){
    	double F,C;
    	cin>>F;
        // scanf("%d", &F);
    	C=5*(F-32)/9;
    	printf("%.5f",C);
    	return 0;
    }
    
  • B2017 打印 ASCII 码

    本题要求一个字符的 ASCII 码值。

    先普及一下 ASCII 码。

    ASCII (( American Standard Code for Information Interchange ): 美国信息交换标准代码)是基于拉丁字母的一套电脑编码系统,主要用于显示现代英语和其他西欧语言。它是最通用的信息交换标准,并等同于国际标准 ISO/IEC 646 。 ASCII 第一次以规范标准的类型发表是在 1967 年,最后一次更新则是在 1986 年,到目前为止共定义了 128 个字符 。 by baidu

    总结一下: ASCII 码就是一种在计算机中存储字符的方式。至于具体值,只需要记住下面的几个:

    1. 0~9 48~57
    2. A~Z 65~90
    3. a~z 97~122

    PS. ASCII 码中以上 3 种字符内部按照严格升序排列,记住大写字母在小写字母之前,且没有连接。

    不过本题我们不需要当场掌握以上内容,因为字符在 C 语言中本身就以ASCII码形式存储,所以只需强制类型转换即可。

    #include<iostream>
    using namespace std;
    int main(){
         char c;//定义
         cin>>c;//输入
         cout<<(int) c;//强制类型转换并输出  A     65
         return 0;
    }
    
  • B2029 大象喝水

    1 d**m3=1 L

    所以将“升”转化为“立方厘米”公式为:

    1000 c**m3=1 L

    可知题中大象要喝 20000 c**m3 的水才解渴。

    又知圆柱体体积公式:

    V=πr2⋅h

    现已知 h,r 以及总喝水数,求大象喝水数。

    易错点:最后要对喝水的桶数取整!(因为 a 大部分不为整数,要向上取整大象才能喝饱)

    #include<bits/stdc++.h>
    using namespace std;
    int h,r,a;
    int main(){
    	cin>>h>>r;
    	a=20000/(3.14*r*r*h)+1;
    	cout<<a;
    	return 0;
    }
    
  • B2041 收集瓶盖赢大奖

    这道题是一道练习分支结构的入门题

    我们把这两种瓶盖的个数称为 ab ,可以根据题目列出这两个表达式:a>=10b>=20

    这两者之间是有其一即可的关系,可以列出如下表达式:a>=10||b>=20,这是这道题的核心。

    或运算符||

    #include<iostream>
    using namespace std;
    int main()
    {
        int a,b;
        bool a=true
        bool b=false
        if(b)
            cout<<1
        else
    		count<<0
        cin>>a>>b; // ||
        if(a>=10||b>=20)
        	cout<<1;
        else
        	cout<<0;
        return 0;
    }
    
  • B2049 最大数输出

    解法1:

    求最大值可以使用 c++ 中自带的 max 函数解决。

    使用格式: max(a1,a2) ,随后会返回 a1a2 中较大的数,三个数的最大值嵌套一下即可。

    #include<bits/stdc++.h>
    using namespace std;
    int a,b,c; 
    int main(){
    	cin>>a>>b>>c;
    	cout<<max(a,max(b,c));//取a与b,c最大值的最大值,也就是a,b,c的最大值
    	return 0;
    }
    

    解法2:

    #include<bits/stdc++.h>
    using namespace std;
    
    signed main()
    {
    	int a, b, c;
    	scanf("%d%d%d", &a, &b, &c);
    	printf("%d\n", max(max(a, b), c)); 
    	return 0;
    }
    

    解法3:

    #include<bits/stdc++.h>
    using namespace std;
    int main(){
    	int a,b,c;
    	cin>>a>>b>>c;
    	cout<<max(max(a,b),c)<<endl;
    	return 0;
    }
    
    
  • B2056 求整数的和与均值

    根据题意,读入 n ,在依次读入 n 个数,将它们累加到 x 中,就得到了它们的和。

    x×1.0÷n 就可以得到它们的均值,最后输出即可。

    注意:输出均值时记得保留 5 位小数!

    #include<bits/stdc++.h>
    using namespace std;
    int main(){
    	int n;
    	int sum=0,a[10010];
    	double ans;
    	cin>>n;
    	for(int i=1;i<=n;i++){
    		cin>>a[i];
    		sum+=a[i];
    	}
    	cout<<sum<<" ";
    	ans=sum;
    	cout<<fixed<<setprecision(5)<<ans/n<<endl;
    	return 0;
    }
    
  • B2063 人口增长问题

    每年人口增加的人数就是 0.001x 人,我们只需要循环 n 年,累加人数,即可。

    解法1:

    #include <iostream> //输入输出
    #include <iomanip> //输出小数setprecision()函数
    using namespace std; //标准命名空间
    
    int main() {
        int n;
        double x;
        cin >> x >> n;
        for(int i = 0; i < n; i++)
            x += x / 1000.0;
        cout << fixed << setprecision(4) << x; //保留4位小数输出
        return 0;
    }
    

    解法2:

    #include <iostream>
    #include <cstdio>
    using namespace std;
    
    int main() {
    	double x;
    	int n;
    	cin >> x >> n;
        for (int i = 1;i <= n; i ++) {
    		x += 0.001*x;
    	} 
    	printf ("%.4lf", x);
    	return 0;
    }
    
  • B2064 斐波那契数列

    斐波那契数列模板题。斐波那契数列定义:第一、二项为1, 后面每一项等于之前两项之和。由定义可得到递推式:f(i)=f(i−1)+f(i−2)。 预处理 f 数组,直接计算即可。对于每次询问,输出对应的 f(i)。

    #include<bits/stdc++.h>
    using namespace std;
    
    long long f[40];
    
    int main() {
        f[1] = 1; f[2] = 1;
        for(int i = 3; i <= 30; i ++) 
            f[i] = f[i - 1] + f[i - 2];
        
        int n, a;
        scanf("%d", &n);   
        while(n--) {
            scanf("%d", &a);
            printf("%lld\n", f[a]);
        }   
        return 0;
    }
    
  • B2060 满足条件的数累加

    本题直接暴力模拟即可。

    一个循环从 m 枚举到 nsum 加上为 17 的倍数的数,最后输出 sum 即可。由于本题 mn 不到 1000 ,不会超时。

    #include<bits/stdc++.h>
    using namespace std;
    
    int main(){
        int m,n,sum=0;  //不需要开long long
    	cin>>m>>n;
    	for(int i=m;i<=n;i++){ 	//从m枚举到n
    		if(i%17==0) sum+=i;	//总和加上为17倍数的数
    	}
    	cout<<sum<<endl;	//输出总和
    	return 0;
    }
    
  • B2078 含 k 个 3 的数

    首先,观察到 1<m≤1015,要开long long
    为什么?
    int 能储存的最大值只有 2147483647,而 2147483647<1015,int 不够了。
    按照那篇文章的计算方式,可知:long long 能储存的最大值是 9223372036854775807,而 1015≤9223372036854775807,所以 long long 够了。

    我们可以先算出 m 里有几个 3,再和 k 比较,如果一样,就输出 YES,反之,输出 NO
    主要流程如下:

    • 初始化计数器 cnt3←0,用来数 m 中有几个 3。
    • 取出 m 的个位,如果是 3,cnt3←cnt3+1
    • 删去 m 的个位
    • 如果 m=0,停止。

    题目要求的就是 m 中 3 的个数,我们可以定义一个计数器 cnt 来储存 3 的个数,再用循环不断对 m 模 10 求 m 的个位,如果是 3 就让计数器加一,最后判断计数器是否与 k 相等。
    注意,每做完一次循环就要对 m 除以 10 ,否则会死循环。

    怎么取出 m 的个位?
    m mod 10 就 OK 了!

    m mmod10
    1 1
    12 2
    123 3
    1234 4

    怎么删去 m 的个位?
    m÷10

    m m÷10
    10 1
    114514 11451
    19260817 1926081
    1314250 131425
    #include <bits/stdc++.h>
    
    using namespace std;
    
    int main(){
    	long long m;
    	int k;
    	cin >> m >> k;//输入。
    	int cnt = 0;//定义计数器。
    	while(m != 0){//循环,不断对m模10。
    		if(m % 10 == 3) cnt++;//如果是3就把计数器加一。
    		m /= 10;//将m模10。
    	}
    	if(k == cnt) cout << "YES";//判断与k相等,满足条件则输出YES,否则为NO。
    	else cout << "NO";
    	return 0;
    }
    
  • B2090 年龄与疾病

    非常直接的方法就是开四个变量 a,b,c,d 分别记录四个区间内数的个数,最后除以 n 算百分比。

    这里就要用到 if…else… 语句。

    语法介绍

    if (语句 1) 操作 1;
    else if (语句 2) 操作 2;
    else if (语句 3) 操作 3;
    ...
    else 操作 n;
    

    代表:

    1. 如果语句 1 成立,则执行操作 1;
    2. 否则,如果语句 2 成立,则执行操作 2;
    3. ……
    4. 如果上述 n−1 个语句都不成立,则执行操作 n

    实现

    对于每个 a**i(i∈[1,n])),挨个判断即可。

    #include <cstdio>
    using namespace std;
    
    int main(){
        int n, a, b, c, d;
        scanf("%d", &n);
        for(int i = 0 ; i < n ; i++){
            int t;
            scanf("%d", &t);
            if(t <= 18) a++;
            else if(t <= 35) b++;
            else if(t <= 60) c++;
            else d++;
        }
        printf("%.2lf\%\n%.2lf\%\n%.2lf\%\n%.2lf\%", a * 100.0 / n, b * 100.0 / n, c * 100.0 / n, d * 100.0 / n);
        return 0;
    }
    
  • B2089 数组逆序重存放

    既然我们存储的时候是从第一个存储到第 n 个,那么要将数组逆序存放,我们就可以从第 n 个开始输出到第 1 个,这样就实现了倒序的操作。

    解法1:

    #include <iostream>
    using namespace std;
    
    int a[105];
    
    int main() {
    	int n;
    	cin >> n;
    	for (int i = 1; i <= n; i ++) {
    		cin >> a[i];
    	}
    	for (int i = n; i >= 1; i --) {
    		cout << a[i] << " ";
    	}
    	//输入从第一个到第n个
    	//输出从第n个到第一个
    	//就实现了倒序 
    	return 0;
    } 
    

    解法2

    #include<bits/stdc++.h>
    using namespace std;
    int main(){
        int n;
        int a[150];
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
             scanf("%d",&a[i]);
        }
        for(int i=n;i>=1;i--){
             printf("%d ",a[i]);
        }
        return 0;
    }
    
  • B2093 查找特定的值

    解法1:顺序查找法

    #include <iostream>
    using namespace std;
    int a[10005];
    int main() {
    	int n;
    	cin >> n;
    	for (int i = 0; i < n; i ++) { 	//下标从0开始 
    		cin >> a[i];
    	}
    	int x;
    	cin >> x;
    	for (int i = 0; i < n ; i ++) { 	//下标从0开始 
    		if (a[i] == x) {	//如果出现相等的情况 
    			cout << i;		//输出下标 
    			return 0;		//同时结束程序 
    		} 
    	} 
    	cout << "-1";			//如果程序未结束,那么就没有x这个元素,则输出-1 
    	return 0;
    }
    

    解法2:对于这道题,我们固然可以一个一个去查找(即“顺序查找法”),但我们还可以用更优的方法——哨兵查找法。“哨兵”指的就是 a**nx 一句中放在 a**n 里的数。只要把 x 放在 a**n 里,当 p=n 时就一定能找到 x,不会出现 *p *> n 的情况。因此,我们就不用在while循环中确认 p 的值是否达到了 n

    #include<iostream>
    using namespace std;
    int n,a[20000],x,p;
    int main(){
    	cin>>n;
    	for(int i=0;i<n;i++){
    		cin>>a[i];
    	}
    	cin>>x;
    	a[n]=x;
    	while(a[p]!=x)p++;
    	if(p==n)cout<<"-1";
    	else cout<<p;
    	return 0;
    }
    

    换句话说,我们把原来的

    while(p<n){
    	if(a[p]==x){
    		cout<<p;
    		return 0;
    	}
    	p++;
    }
    cout<<"-1";
    return 0;
    

    写成了

    while(a[p]!=x)p++;
    if(p==n)cout<<"-1";
    else cout<<p;
    return 0;
    

    不但使代码看上去更加简洁,还省去判断 p 是否等于 n 的语句,节约了大约 41 的时间。在 n≤10000 时,节约的时间还不明显。但当 n 达到 1×10*5 甚至是 1×10*6 时,函数的执行时间就会有显著差距了。

  • B2081 与 7 无关的数

    
    

专题