- ベストアンサー
たぶん初歩の問題ですが。。。
短大のプログラミングの授業で、問題が出されました。 『斜辺の長さが50以下で、3辺の長さがすべて整数の直角三角形となる場合は何通りあるかを計算させる処理を書きなさい。ただし、同じ数値の順番だけが違うものは一通りとします。 ヒント:Cを斜辺とする三角形A、B、Cは次の条件を満たしています。 Aの2乗+Bの2乗=Cの2乗 (2乗の書き方が分かりませんでした。ごめんなさい) 50以下のすべての3つの正の整数の組み合わせについて、この式が成り立っているかどうかを調べる。同じ数値の順番だけが違うものを除くにはどうすればよいかを考えてください。』 という問題なんですけど、ぜんぜん分からないんです(><)汗汗 いくら考えても、どう考えていいか全然分かりません。。。 プログラミング超初心者なんですけど、誰か教えて下さい!!
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
前の解答より単純な解き方が出来ました。 「’」は注釈です。 このままPrivate Sub以下をVBE画面に コピーすれば良いと思います。 Private Sub Form_Click() '1から50までの2乗数を配列s(1)からs(50)に '持ちます。 Dim s(51) As Integer u = 0 '解答数 For i = 1 To 50 s(i) = i * i Next i ' 縦横2次元の表を考えてください. '縦にs(i)の数を並べ、横にも 's(i)の数を並べた表を考えてください。 '縦のi番目にある数a(i)(=aの2乗)と横の番目に 'ある数s(j)(=bの2乗)を考えます。 'この和をs(i)+s(j)=tとすると、tはs(1)からs(50)の '中にあるはずです。 'tの計算は For i = 1 To 50 For j = 1 To 50 t = s(i) + s(j) '---- For k = 1 To 50 If t = s(k) Then ’tが平方数の配列に見つかるか Form1.Print "a power(2)="; s(i), Form1.Print "b power(2)="; s(j), Form1.Print "c power(2)="; t u = u + 1 End If Next k '------- Next j Next i Form1.Print "-----" Form1.Print u ' u=40組ですからダブりで数えているので、20通りが解答です。 End Sub
その他の回答 (4)
- TAGOSAKU7
- ベストアンサー率65% (276/422)
サンプルを作りました。 斜辺以外の2辺を、[i/j]のループカウンタの値を使用しています。 iが1~50 jが1~50 のループにしてしまうと i = 3 ; j = 4 i = 4 ; j = 3 となってしまうので、 iが1~50 jがi~50 のループとしています。 これによって、データの重複が存在しなくなります。 > If lngMaxLimit < lngCalc Then > Exit For > End If というのは、斜辺のべき乗の最大値(この問題の場合は2500)を超えるような斜辺の時は、Jカウンタのループを抜ける処理になってます。 > sngCalc = lngCalc ^ 0.5 > lngWork = sngCalc というのは、i/jより算出した斜辺の値に平方根の処理をおこない、変数sngCalcに代入されます。 それを小数点以下を切り捨て、変数lngWorkに代入してます。 この切り捨て前・後が同じ値であれば、斜辺は整数であると言えます。 Sub Main() Dim lngMaxHypotenuse As Long '斜辺の上限 Dim lngMaxLimit As Long '斜辺の上限のべき乗 Dim lngCalc As Long '斜辺以外のべき乗どうしを加算した時の値、計算ワーク Dim sngCalc As Single '斜辺以外のべき乗どうしを加算した時の値を平方根にかけたもの、計算ワーク Dim lngWork As Long 'sngCalcで得た値の、小数点以下切り捨てした値 Dim i As Long 'Iループカウンタ Dim j As Long 'Jループカウンタ Dim ansCount As Long '見つかった回答件数 Dim ansStr() As String '回答を収める配列 Dim strOutPut As String '回答を出力する文字列 '回答の初期化 Erase ansStr ansCount = 0 '斜辺MAX値 lngMaxHypotenuse = 50 '斜辺2乗の値を超えることはありえないので、上限をセット lngMaxLimit = lngMaxHypotenuse ^ 2 For i = 1 To lngMaxHypotenuse For j = i To lngMaxHypotenuse 'このときの斜辺のべき乗の値を求める lngCalc = (i ^ 2) + (j ^ 2) 'もし斜辺の2乗の値が上限を超えたら、Jカウンタのループを抜ける If lngMaxLimit < lngCalc Then Exit For End If '斜辺のべき乗から平方根により、斜辺の値を求める sngCalc = lngCalc ^ 0.5 'ロング型の変数にセットする(この時斜辺の値に小数点以下が存在するとき、切り捨てられる) lngWork = sngCalc '小数点以下を切り捨てする前と、切り捨てた後が同じ値ならば、整数値の3辺である If (lngWork = sngCalc) Then ReDim Preserve ansStr(ansCount) As String ansStr(ansCount) = i & " / " & j & " → " & lngWork ansCount = ansCount + 1 End If Next j Next i '答えの出力 If ansCount > 0 Then strOutPut = Join(ansStr, vbNewLine) Else strOutPut = "斜辺は求められませんでした。。。" End If MsgBox strOutPut End Sub
お礼
おお!!なんか、長々と書いて頂いてしまって、申し訳ないです!!(><)っっ本当に有難うございました!!なんか申し訳ないんですけど、初心者なんで、まだ習ってない文字とかがいっぱいで、よく分からなかったです。。。でも、回答をもとに、よく考えてみますね。ありがとうございました!!
- yusuke5111
- ベストアンサー率16% (9/55)
3重のループを使えば良いです 1番最初のループは、1から50まで、これが斜辺になります。---(1) 2番目のループは、1から(1)未満まで、((1)が斜辺なので1番長いです。)---(2) 3番目のループは、1から(2)以下までループさせて、----(3) それそれ、(2)^2+(3)^2=(1)^2を満たすものの数を数えれば出てきます。 こうすれば、各組み合わせ1度ずつ出てきます。 また、高速化のために、下記の方のヒントを利用し、 (2)^2+(3)^2が(1)^2より大きくなると(3)のループを抜ける等してください。
お礼
本当にありがとうございました!! 基礎が出来てないから、じっくり考えてみないと分かりそうもないんですけど、 回答をもとに、じっくり考えてみる事にします!!ありがとうございました!!
- bin-chan
- ベストアンサー率33% (1403/4213)
すいません。題意の読み取りを誤りました。 > 同じ数値の順番だけが違うものを除くにはどうすればよいかを 出てきた答え(A,B,C)の順序を問わないということなので 各辺の値を昇順または降順に整列してから比較してみてください。
お礼
また、わざわざありがとうございました!! 参考にしてみます。
- bin-chan
- ベストアンサー率33% (1403/4213)
ヒント 三角形のある一辺は他の2辺の計より短い。 (そうでなければ閉じた図形にならない)
お礼
どうも、ほんとうに有難うございました!!! なんか、とても早く回答して頂いたみたいで(^O^) これをもとに良く考えてみますね!!!
お礼
回答本当に有難うございました!! なんとか分かりそうです(^ー^)☆☆ よーく考えてみてます。ありがとうございました!!!