全国青少年信息学奥林匹克竞赛(信奥赛)备考实战之循环结构(while循环应用)

在 C++ 编程的世界里,循环结构是掌控程序流程的关键工具之一,而while循环更是其中的经典。它就像一个不知疲倦的小卫士,只要条件满足,就会持续执行特定的代码块,可以解决诸多复杂的编程任务。本文就一同深入探索while循环的精彩应用。

一、基础语法回顾

while循环的基本语法形式简洁明了:

cpp 复制代码
while (条件表达式) {
    // 循环体,包含需要重复执行的代码
}

当程序运行到while语句时,首先会对 "条件表达式" 进行求值。若结果为true(在 C++ 中,非零值即为true),则进入循环体执行其中的代码;执行完毕后,再次回到条件表达式处进行判断,如此往复,直到条件表达式的值变为false,此时程序跳出while循环,继续往后执行其他代码。

二、常见应用场景

实战训练1---分离整数的各个数位

问题描述:

给定一个整数 n(1≤n≤100000000),要求从个位开始分离出它的每一位数字。从个位开始按照从低位到高位的顺序依次输出每一位数字。

输入格式:

一行一个整数,输入一个整数n,整数n在1到100000000 之间。

输出格式:

一行,从个位开始按照从低位到高位的顺序依次输出每一位数字。数字之间以一个空格分开。

输入输出样例:

|--------|-------------|
| 输入样例1 | 输出样例1 |
| 12345 | 5 4 3 2 1 |
| 输入样例2 | 输出样例2 |
| 985211 | 1 1 2 5 8 9 |

问题分析:

根据题意,要从个位开始分离出整数的每一位数字,可以利用取模运算%和整除运算/的特性。对于输入的整数n,对n进行求模运算可以得到个位数字,例如对于数字123,123%10的结果是3,这就是想要分离出的个位数字;在得到个位数字并输出后,为了继续分离下一位数字,需要将 n 更新为去掉当前个位数字的新数字,这可以通过整除运算来实现,例如对于数字 123,在输出 3 后,将 n 更新为 123 / 10,结果是 12,这样就可以继续分离下一位数字。重复上述过程,直到 n 为 0,此时表示已经将所有位的数字都分离并输出。由于并不知道n的位数,所以使用while循环来实现,条件表达式为n>0,循环体为取模运算和整除赋值运算,并输出取模运算的结果。具体程序代码如下所示:

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int main(){
	int n;//定义一个整数n 
    cin>>n;//输入整数n的值 
    while(n>0){//只要n不等于0,就执行循环体 
        cout<<n%10<<" ";//首先输入最低位数,最低位数为n对10取模运算 ,并输出最低位数 
        n = n/10;//将n除以10之后重新赋值给n 
    }
    return 0;
}

实战训练2---数字统计问题

问题描述:

请统计某个给定范围L,R 的所有整数中,数字2出现的次数。比如给定范围 2,22,数字 2在数2中出现了1次,在数12中出现1次,在数 20 中出现1次,在数21 中出现1次,在数 22中出现2次,所以数字2在该范围内一共出现了6次。

输入格式:

输入一行,输入两个整数L和R,这两个整数之间用空格隔开。

输出格式:

输出一行一个整数,表示2出现的次数。

输入输出样例:

|-------|-------|
| 输入样例1 | 输出样例1 |
| 4 23 | 6 |
| 输入样例2 | 输出样例2 |
| 10 30 | 11 |

问题分析:

对于范围 L, R 内的每一个整数,都需要进行数位分离求出其每一位数字,以便检查其中数字 2 的出现情况,分离整数各个数位可以使用实战训练1中的思想来解决,即使用while循环,条件表达式为该整数大于0,循环体内执行取模和整数运算;由于需要对区间内所有的整数都要执行一次操作,所以该问题是嵌套循环,内层循环为分离数位的while循环,外层循环次数确定,外层循环可以采用for来实现,循环变量起始值为L,终值为R,更新表达式为自增运算,while循环是for的循环体;此外还需要一个变量 sum来存储数字 2 在整个范围 L, R 内的出现总次数。遍历范围 L, R 内的每一个整数,对于每个整数,使用上述的数字分离和检查逻辑来计算数字2的出现次数,并累加到 sum中。具体程序代码如下:

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int main(){
    int l,r,sum=0;//定义整数的范围变量l和r,以及数字2出现的总次数变量sum,并将sum初始化为0 
    cin>>l>>r;//输入l和r的值 
    for(int i=l;i<=r;i++){//外层循环,体现对于[l,r]范围的每一个整数都执行找数字2的操作 
        int tmp = i;//数位分离时要修改该整数,为了防止i发生变换,将i赋值给临时变量tmp 
        while(tmp){//对该整数进行数位分离 
            if(tmp%10 == 2){//判断最低位是否为2 
                sum++;//将2出现的次数进行自增运算 
            }
            tmp /= 10;//修改整数的值 
        }
    }
    cout<<sum<<endl;//输出2出现的次数 
    return 0;
}

实战训练3---数1的计数问题

问题描述:

给定一个正整数 n(1≤n≤10000),写下从1到n的所有整数,然后数一下其中出现的数字1的个数。例如当n=2 时,写下1,2。这样只出现了1 个1;当n=12 时,写下1,2,3,4,5,6,7,8,9,10,11,12。这样出现了5 个1。

输入格式:

输入一行一个整数n。

输出格式:

输出一行一个整数表示数字1出现的个数。

输入输出样例:

|-------|-------|
| 输入样例1 | 输出样例1 |
| 20 | 12 |
| 输入样例2 | 输出样例2 |
| 30 | 13 |

问题分析:

根据题意求解数字1出现的次数,该题目和训练2的题目类似,不同之处在于首先范围的变化,训练2为输入范围 L, R ,而该题目是输入一个整数n,范围变成1,n,其次训练2为判断数字2的次数,而该题目为数字1的个数,剩余内容一样,可以参考训练2,具体程序代码如下:

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int main() {
	int n,sum = 0;//定义整数的右范围变量n,以及数字1出现的总次数变量sum,并将sum初始化为0 
	cin>>n;//输入n的值 
	for(int i=1;i<=n;i++){//外层循环,体现对于[1,n]范围的每一个整数都执行找数字2的操作
		int tmp=i;//数位分离时要修改该整数,为了防止i发生变换,将i赋值给临时变量tmp
		while(tmp>0){//对该整数进行数位分离 
			if(tmp%10 == 1){//判断最低位是否为1
				sum++;//将1出现的次数进行自增运算 
			}
			tmp=tmp/10;//修改整数的值
		}
	}
	cout<<sum<<endl;//输出1出现的次数
	return 0;
}
相关推荐
数据皮皮侠1 分钟前
全国消协智慧 315 平台投诉信息数据库
大数据·人工智能·算法·百度·制造
JSMSEMI113 分钟前
JSM12N60C 600V N沟道增强型功率MOSFET
开发语言·javascript·ecmascript
设计师小聂!4 分钟前
Java异常处理
java·开发语言·后端·编辑器·idea
清水白石0087 分钟前
从打印对象到高质量调试:彻底理解 Python 中 `__repr__` 和 `__str__` 的区别
开发语言·python
8Qi89 分钟前
LeetCode 115 & 392:不同子序列 / 判断子序列
算法·leetcode·职场和发展·动态规划
枕星而眠12 分钟前
C++ 面向对象核心机制深度解析:多态性、虚函数、虚继承与 final 类
运维·开发语言·c++·后端
小蒋学算法28 分钟前
算法-乘法表中第K小的数-二分
数据结构·算法
智者知已应修善业37 分钟前
【51单片机8个LED,已经使用了D1D2,怎么样在不动D1D2的前提下实现D6~D8的流水灯】2024-1-19
c++·经验分享·笔记·算法·51单片机
Evand J39 分钟前
【MATLAB例程】自适应渐消扩展卡尔曼滤波(AFEKF)三维雷达目标跟踪|效果已调优,附下载链接和运行结果,代码直接运行即可
开发语言·算法·matlab·目标跟踪·卡尔曼滤波·自适应滤波·代码定制
坚果派·白晓明40 分钟前
鸿蒙PC适配实战:simdjson 三方库移植攻略与 AtomCode Skills 提效之道
c++·harmonyos·三方库·skills·atomcode·c/c++三方库·c/c++三方库适配