今回は、二重ループの最終問題に挑戦!ループ問題のポイントは条件式などを工夫して明らかに無駄な計算を減らすこと!
問題概要
Nが与えられて、三辺の長さが整数かつ和がNになる直角三角形が存在するかを判定する。
入力例:
12
出力例:
YES
❌ NG例
const rl = require('readline').createInterface({input:process.stdin});
rl.once('line', (input) => {
const N = Number(input);
let result = false;
for(let a = 1; a < N; a++){
for(let b = 1; b < N; b++){
const c = N - (a + b);
if (a ** 2 === b ** 2 + c ** 2) {
result = true;
}
}
if(result){
console.log("YES");
return;
}
}
console.log("NO");
rl.close();
});
❌問題点
三角形の辺のうち、直角三角形では:
- 斜辺(a)が一番長い辺である必要がある
- よって他の辺(b, c)は、aより小さい必要がある
❌ ミスになる条件:b < N
これは b が a より長くなる可能性がある ので、三平方の定理が成立しない or 正しく判定できない ことがある。
✅改善点
①無駄な計算を省く:
if (c <= 0 || c >= a) continue;
- c も有効な長さでなければスキップ
-
continue
は「次のループにスキップしたいとき」に使う
②必要のないフラグ:
直角三角形が成り立つとなったとき、true にしてどうこうするより、ストレートに”YES”と出力して終了すればいいだけ。
✅ OK例:
const rl = require('readline').createInterface({ input: process.stdin });
rl.once('line', (input) => {
const N = Number(input);
for (let a = 1; a < N; a++) {
for (let b = 1; b < a; b++) {
const c = N - a - b; //(三辺の和がNより)
if (c <= 0 || c >= a) continue;
// 三平方の定理のチェック
if (a * a === b * b + c * c) {
console.log("YES");
rl.close();
return;
}
}
}
console.log("NO");
rl.close();
});
🗒️メモ&まとめ
-
a² = b² + c² だけでなく、a > b, c のチェックも大事
-
組み合わせは全探索でも、制限つきで効率化できる
-
a ** 2
よりa * a
の方が見やすいかも -
continue
で無駄なループはスキップ!