lc

发布时间 2023-09-27 18:05:06作者: actypedef

有关循环的基本知识

三种基本的循环

1. while

while (expression:condition) {
    commands;
}

2. do while

do {
    commands;
} while (expression:condotion);

上述代码等效于

commands;
while (exp:condition) {
    commands;
}

3. for

for (exp:init ; exp:condition ; exp:increment) {
    commands;
}

上述代码等效于

exp:init
while (exp:condition) {
    commands;
    exp:increment;
}

特别的:for循环的三个语句可以部分或者全部为空
例如:

for (;;) {
    commands;
}

上述for循环的三个表达式全部为空
该循环如果没有 break 语句,将是一个死循环

break & continue

break

break 表示退出当前循环(也就是break外的第一个循环)

continue

continue表示结束单次循环,继续下一轮循环

breakcontinue都必须在循环内,否则编译错误 (compile error)

循环嵌套

循环嵌套本身没有什么特别的地方,就是循环里面还有一个循环,例如:

while (condition A) { //loop A
    //something
    while (conditionB) { //loop B
        //someting2
    }
    //somting3
}

在上述例子中,每一次循环A的内容是循环B(以及一些可能有的其他代码)

循环嵌套语法不难,真正的难点在于想明白每层循环的条件 (condition) 和语句
作为初学者,可以尝试先想明白每一步要做什么,然后再去写代码

一些例子

数组的遍历 (Traversal)

数组的遍历,就是按照一定的顺序访问数组的每一个元素

数组的遍历一般用for循环完成

遍历一个数组,输出每一个元素

//已知一维数组a中包含n个元素
for (int i=0;i<n;i++) { //注意数组的索引从0开始
    cout<<a[i];
}

多组输入数据的处理

许多题目的输入包含多组输入数据,而处理多组数据实际上就是在循环进行一个相同的步骤

输入多组整数a、b,输出a+b。当a、b均为0是标志输入结束。不要处理结束标志

int a,b;
cin>>a>>b;
while (a!=0 || b!=0) {
    cout<<a+b;
    cin>>a>>b; //将输入放在循环后面,可以方便在输入后马上判断a、b是否为零
}

当然也可以这样写:

int a,b;
while (true) { //while (1)也可以
    cin>>a>>b;
    if (a==0 && b==0) {
        break;
    }
    cout<<a+b;
}

其实还可以这样写:

int a,b;
//逗号隔开的表达式,从左到右先后处理,最后只取最后一个表达式的值
while (cin>>a>>b , (a!=0 || b!=0)) {
    cout<<a+b;
}

上述三种代码的共同点在于输入后马上判断a、b是否为0
这是为了符合题目中 “结束标志不处理” 的要求

判断质数

输入一个正整数,判断它是不是质数

int n;
cin>>n;
bool ok=true;
//质数的标志在于处1和自身外没有约数
for (int i=2;i<n;i++) {
    if (n%i == 0) { //n除以i等等0表示:i是n的约数(或者说:n可以被i整除)
        ok=false;
        break; //找到一个约数就已经不是质数了。之后的循环已经没有意义
    }
}
if (ok) {
    printf("Yes");
}
else {
    printf("No");
}

上述代码有优化方案,以后再说

题目

3-A

题目描述

In the online judge system, a judge file may include multiple datasets to check whether the submitted program outputs a correct answer for each test case. This task is to practice solving a problem with multiple datasets.
Write a program which reads an integer x and print it as is. Note that multiple datasets are given for this problem.

  • 输入

The input consists of multiple datasets. Each dataset consists of an integer x in a line.
The input ends with an integer 0. You program should not process (print) for this terminal symbol.

  • 输出

For each dataset, print x in the following format:
Case i: x
where i is the case number which starts with 1. Put a single space between "Case" and i. Also, put a single space between ':' and x.

讲解

注意到题目中有多组数据,所以要用到循环
而且题目还有求输出数据的编号i,所以for循环是比较符合本题的 (自然的,while也可以)

for (int i=1;;i++) {
    cin>>n;
    if (n==0) {
        break;
    }
    cout<<"Case "<<i<<": "<<x<<endl; //注意空格!!!
}

特别强调:文本比较类的题目,输出必须和题目要求一模一样,空格不能少不能多,大小写不能错,全半角不能错。一个字符的错误,哪怕意思是一样的,也会导致答案错误 (Wrong Answer)
特别的,忽略行末空格和文末换行

3-D

题目描述

Write a program which reads three integers a, b and c, and prints the number of divisors of c between a and b (included) .

  • 输入

The input consists of multiple datasets . Each dataset consists of two integers a, b and c separated by a single space.
The input ends with three 0 (when both a, b and c are zero). Your program should not process for these terminal symbols.

  • 输出

Print the number of divisors in a line.

讲解

部分词语翻译
divisor 约数
between a and b (included) 闭区间[a, b]

如何体现 “约数”

num % i == 0 //代码A

如何求约数数量?循环!

//代码B
int ans=0;
for (int i=a;i<=b;i++) {
    if (代码A) {
        ans++; //相当于ans=ans+1
    }
}

又注意到题目要求处理多组数据,而多组数据的处理是用循环实现的。也就是需要循环执行代码B

while (proper condition) {
    proper input;
    代码B
}