


《数三角形的秘密》
📖 一、故事背景:三角形王国 🏰
1、在 三角形王国 里,有一种特别的三角形,叫做:
直角三角形
2、它有:
-
两条直角边(互相垂直 📐)
-
一条斜边
3、国王提出了一个问题:
👉 如果两条直角边的长度都是 不超过 N 的正整数
👉 有多少个直角三角形,它们的面积是整数?
4、我们的任务:
🎯 帮国王数清楚,一共有多少个这样的三角形!
🧠 二、先别急写代码,先想清楚!
1️⃣ 面积公式(先搞清楚)

2️⃣ 什么时候面积是"整数"?
(1)面积是整数 ⇔
cpp
a × b 是 偶数
(2)📌 因为:
-
偶数 ÷ 2 = 整数
-
奇数 ÷ 2 = 0.5(不是整数)
🧩 三、把问题拆成"小任务"
1、🎯 总目标
数一数有多少组 (a, b),满足:
-
a、b 是正整数
-
a ≤ N
-
b ≤ N
-
面积是整数
2、⚠️ 重要规则
题目说:
两个三角形
(a, b)和(b, a)是 同一个
也就是说:
👉 3 和 4
👉 4 和 3
只能算 一次 ❗
3、✅ 解决办法
我们规定:
cpp
b 从 a 开始枚举
这样就不会重复数。
🧮 四、用小例子先算一遍
🌟 假设 N = 3
所有可能的 (a, b):
| a | b | a×b | 面积 | 合格? |
|---|---|---|---|---|
| 1 | 1 | 1 | 0.5 | ❌ |
| 1 | 2 | 2 | 1 | ✅ |
| 1 | 3 | 3 | 1.5 | ❌ |
| 2 | 2 | 4 | 2 | ✅ |
| 2 | 3 | 6 | 3 | ✅ |
| 3 | 3 | 9 | 4.5 | ❌ |
👉 一共 3 个
🧠 五、把思路翻译成"程序语言"
采用枚举算法:
用 两层 for 循环 枚举直角边
如果
a * b是偶数,就计数加 1
💻 六、参考程序
cpp
#include <iostream>
using namespace std;
int main() {
int N;
cin >> N;
int cnt = 0; // 用来数三角形的数量
// 枚举第一条直角边
for (int a = 1; a <= N; a++) {
// 枚举第二条直角边(从 a 开始,避免重复)
for (int b = a; b <= N; b++) {
// 判断面积是否为整数
if ((a * b) % 2 == 0) {
cnt++;
}
}
}
cout << cnt << endl;
return 0;
}
🧩 七、关键代码逐句讲解
🔹 1. 为什么 b = a 开始?
cpp
for (int b = a; b <= N; b++)
👉 防止 (3,4) 和 (4,3) 重复计算
👉 这是得分的关键细节!
🔹 2. 为什么只判断 (a * b) % 2 == 0?
cpp
if ((a * b) % 2 == 0)
因为:
-
偶数 ÷ 2 = 整数
-
面积就一定是整数
不用真的去算面积,省时间、省麻烦!
🎯 八、考试常见扣分点
❌ 错误 1:内循环,写成 b = 1,从1开始,有重复
→ 会重复算
❌ 错误 2:判断面积为整数, 判断条件写成赋值"="!
(a * b) % 2 = 0,
→ 会出错
❌ 错误 3:cnt 忘记 赋初值为 0,cnt++结果就会错!
🧩九、附:枚举算法通用模版:
🟡 模板 1:从 1 数到 N(最基础)
1、🎒 小故事
老师要点名,从 1 号到 N 号,一个都不漏。
2、💻 模板代码
cpp
for (int i = 1; i <= N; i++) {
// 用 i 做事情
}
3、🌟 常见用途
-
数数
-
累加
-
判断奇偶
🟡 模板 2:区间枚举(L 到 R)
1、🎒 小故事
从第 L 本书,看到第 R 本书。
2、💻 模板代码
cpp
for (int i = L; i <= R; i++) {
// 检查 i
}
🟡 模板 3:双重枚举(两层 for)
1、🎒 小故事
每一对都试试
2、💻 模板代码
cpp
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= M; j++) {
// (i, j) 是一组情况
}
}
3、🌟 典型用途
-
表格
-
两个数的组合
-
二维问题
🟡 模板 4:防止重复的双枚举(非常重要 ⭐)
1、🎒 小故事
选两个人握手,A 和 B、B 和 A 是同一次
2、💻 模板代码
cpp
for (int i = 1; i <= N; i++) {
for (int j = i; j <= N; j++) {
// (i, j) 不重复
}
}
3、🌟 考试常见
-
本题三角形判断
-
配对问题
🟡 模板 5:带条件的枚举(if 判断)
1、🎒 小故事
只数"戴帽子的小朋友" 🎩
2、💻 模板代码
cpp
for (int i = 1; i <= N; i++) {
if (条件) {
// 满足条件才做事
}
}
3、🌟 例子
cpp
if (i % 3 == 0)
🟡 模板 6:枚举 + 计数器(考试最爱)
1、🎒 小故事
看到一个符合要求的,就在本子上打 ✔
2、💻 模板代码
cpp
int cnt = 0;
for (int i = 1; i <= N; i++) {
if (条件) {
cnt++;
}
}
🟡 模板 7:枚举 2 的幂
1、🎒 小故事
数字会"翻倍生长" 🌱
2、💻 模板代码
cpp
for (int x = 1; x <= N; x *= 2) {
// x = 1, 2, 4, 8, ...
}
🟡 模板 8:枚举数组(数组索引)
1、🎒 小故事
检查一排盒子里的东西 📦
2、💻 模板代码
cpp
for (int i = 0; i < n; i++) {
// a[i]
}
🟡 模板 9:枚举字符串中的字符
1、🎒 小故事
一个字母一个字母读 📖
2、💻 模板代码
cpp
for (int i = 0; i < s.length(); i++) {
char c = s[i];
}
🟡 模板 10:枚举二维数组(二维数组索引)
1、🎒 小故事
走棋盘 ♟️
2、💻 模板代码
cpp
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
// a[i][j]
}
}
🧠 枚举算法"必背三句话"
📌
1️⃣ 枚举 = 不偷懒,一个一个来
2️⃣ for 写对范围,成功一半
3️⃣ 重复问题 → 第二层从 i 开始
🎯 GESP考试"万能枚举套路"
cpp
读题
↓
想清楚:枚举什么?
↓
for 循环写出来
↓
if 判断条件
↓
cnt++
↓
输出