题解:P5719 【深基4.例3】分类平均
P5719【深基4.例3】分类平均
分析
要找到所有 A、B 两类数各自的均值,可以从小到大枚举
想要判断一个数字
代码
C++
在 C++ 里,可以用如下的 for 循环将 for (int i = 1; i <= n; ++i) { Block }。而 Block 的内容需要根据前文的分析,用 if-else 结构判断
for (int i = 1; i <= n; ++i) {
if (i % k == 0) { // i 是 A 类数
sumA += i; // 累加 A 类数的和
++cntA; // 累加 A 类数的个数
} else { // 否则是 B 类数
sumB += i; // 累加 B 类数的和
++cntB; // 累加 B 类数的数量
}
}
由于 for 循环的循环体里只有一个 if-else 结构,包裹循环体的花括号可以省略,只留 if-else 结构自身的花括号,结合相应的变量声明和读入,可以写出如下代码:
#include <bits/stdc++.h>
using namespace std;
int main() {
int n, k;
cin >> n >> k;
int sumA = 0, sumB = 0, cntA = 0, cntB = 0;
for (int i = 1; i <= n; ++i) if (i % k == 0) { // 这里的花括号是 if 的
sumA += i;
++cntA;
} else {
sumB += i;
++cntB;
}
cout << fixed << setprecision(1) << 1.0 * sumA / cntA << " " << 1.0 * sumB / cntB << endl; // 按规定进行输出
}
这里输出较为复杂。其中 fixed 是要求总是按小数形式进行输出(而不是科学计数法),setprecision(x) 表示后面的浮点数保留的小数点后位数为
因为 sumA 和 cntA 都是整数,直接对两个整数做除法得到的结果是整除而不是浮点数形式,所以必须在运算前先用浮点数 1.0 乘一下。这是因为:浮点数乘以整数的结果是浮点数。在从左到右运算时,先算 1.0 * sumA,得到了一个浮点类型的结果,把这个结果去除 cntA,就是浮点型除以整形,结果就能得到浮点型了。
Rust
在 Rust 里,进行与上文类似的循环的方法是 for i in 1..=n { Block }。相比循环 for _ in 0..n { Block },这里有两个改变:
- 把循环变量的声明从
_改为了i。这是因为 Rust 不允许在代码里拿到_的值(可以改成_试一下),但是我们需要在循环体里拿到循环变量的值进行判断,所以需要用一个不是_的标识符。 - 循环范围从
0..n变成了1..=n。前者的循环范围是0,1,2,\dots n - 1 这n 个数,后者是1,2,\dots , n 这n 个数。其中对右边界的取等是通过=标识的。
Rust 不允许省略 for 循环体的大括号,而 Rust 的 if 条件无需加括号,可以写出代码如下:
/*
省略了读入类
https://www.luogu.com.cn/paste/clle55rg
*/
fn main() {
let mut cin = Scanner::new();
let (n, k) = (cin.next_int(), cin.next_int());
let (mut sum_a, mut sum_b, mut cnt_a, mut cnt_b) = (0, 0, 0, 0);
for i in 1..=n {
if i % k == 0 {
sum_a += i;
cnt_a += 1;
} else {
sum_b += i;
cnt_b += 1;
}
}
println!("{:.1} {:.1}", sum_a as f64 / cnt_a as f64, sum_b as f64 / cnt_b as f64);
}
关于输出,{:.1} 是输出一位小数的方法,Rust 不允许浮点数和整数相除,因此必须把两个量都显式地转换成 f64 浮点型。
TypeScript
在 ts 里,类似的 for 循环方法是 for (let i = 1; i <= n; ++i) { Block }。它的 for 和 if 风格都和 cpp 几乎一致。值得一提的是 number 本身就是浮点型,因此无需做类型转换就可以直接除。
import { Reader } from './Reader';
// https://www.luogu.com.cn/paste/r7vtnbaz
import * as fs from 'node:fs';
const data = fs.readFileSync('/dev/stdin')
const lines = data.toString('ascii').trim().split('\n');
const cin = new Reader(lines);
let n = cin.nextInt(), k = cin.nextInt();
let sumA = 0, sumB = 0, cntA = 0, cntB = 0;
for (let i = 1; i <= n; ++i) if (i % k == 0) {
sumA += i;
cntA++;
} else {
sumB += i;
cntB++;
}
console.log(`${(sumA / cntA).toFixed(1)} ${(sumB / cntB).toFixed(1)}`)