互いに既約な数について

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
nanase

互いに既約な数について

#1

投稿記事 by nanase » 8年前

x, y, z は1 から100 までの整数から選ばれるとして,
x * x + y * y = z * z
を満たす(x, y, z) の組み合わせをすべて求めて表示するプログラムを作成せよ.ただし,x, y は
x ≦ y の関係があるものに限る.

さらにx,y,z が互いに既約な(公約数をもたない) 組み合わせだけを表示するプ
ログラムに挑戦してみよ.
という問題がだされたのですが、

#include <stdio.h>
#include <math.h>

#define NUM_MAX 100.0

int main(void)

{
double x, y, z;

for (x = 1.0; x < NUM_MAX; x++) {
for (y = 1.0; y < NUM_MAX; y++) {
if (x >= y)
continue;

z = sqrt(x * x + y * y);
if (z == ceil(z))
printf(" X = %2.0lf, Y = %2.0lf, Z = %2.0lf\n", x, y, z);
}
}
return 0;
}

ここまでしかわからずここからどうすれば既約の数を除けるかわかりません。
すいませんが教えてもらえないでしょうか。

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: 互いに既約な数について

#2

投稿記事 by みけCAT » 8年前

ソースコードを提示する際はBBCodeを有効にした(無効にしない)状態でcodeタグで囲んでいただけると、見やすくてありがたいです。
nanase さんが書きました:ここまでしかわからずここからどうすれば既約の数を除けるかわかりません。
すいませんが教えてもらえないでしょうか。
任意の2個の正の整数は公約数1をもつので、既約な(公約数をもたない)組み合わせはありません。よって、全ての組み合わせを除けば既約の数を除けます。

もしも2以上の公約数をもつ組み合わせのみを除きたいのであれば、ユークリッドの互除法などで最大公約数を求め、
最大公約数が1でない組み合わせを除けばいいでしょう。
aとbの最大公約数をgcd(a,b)とすると、a,b,cの最大公約数はgcd(a,gcd(b,c))で求められます。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

nanase

Re: 互いに既約な数について

#3

投稿記事 by nanase » 8年前

ありがとうございます。
2以上の公約数を持つ場合を除きたいのでユークリッドの互除法を調べて
挑戦してみます。

ソースコードについては次回からは気を付けます。
ご指摘ありがとうございました。

box
記事: 2002
登録日時: 13年前

Re: 互いに既約な数について

#4

投稿記事 by box » 8年前

nanase さんが書きました:x, y, z は1 から100 までの整数から選ばれるとして,
と言っているにもかかわらず、実際には
nanase さんが書きました:

コード:

    double x, y, z;
double型を使っています。矛盾していませんか?
nanase さんが書きました:

コード:

    for (x = 1.0; x < NUM_MAX; x++) {
        for (y = 1.0; y < NUM_MAX; y++) {
100を含まないようになっている点も、題意と矛盾していませんか?
また、double型の数に++演算子を適用して大丈夫なんでしょうか。
少なくとも私はやったことがありません。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

nanase

Re: 互いに既約な数について

#5

投稿記事 by nanase » 8年前

ご指摘ありがとうございます。
私なりに書き換えてみました。
#include <stdio.h>
#include <math.h>

#define NUM_MAX 101.0

int main(void)

{
int x, y;
double z;

for (x = 1.0; x < NUM_MAX; x++) {
for (y = 1.0; y < NUM_MAX; y++) {
if (x >= y)
continue;

z = sqrt(x * x + y * y);
if (z == ceil(z))
printf(" X = %2.0d, Y = %2.0d, Z = %2.0lf\n", x, y, z);
}
}
return 0;
}

これなら大丈夫ですかね?

box
記事: 2002
登録日時: 13年前

Re: 互いに既約な数について

#6

投稿記事 by box » 8年前

何で平方根が出てくるのかが謎です。
素直に

コード:

    if (x * x + y * y == z * z) {
        // 題意を満たしている
    }
とかいう風に書けばいいものを…
sqrtやceilを持ち出してきている結果、わざわざややこしく書いているように思えてなりません。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

nanase

Re: 互いに既約な数について

#7

投稿記事 by nanase » 8年前

ありがとうございます。
難しく考えすぎてました。すいません。

x、y、zが公約数を持たないようにするプログラムがやっぱりよくわかりません。
ユークリッドは調べたんですがどのようにして今のプログラムに付け加えればいいかわかりません。
すいませんが詳しく教えてもらえないでしょうか。

box
記事: 2002
登録日時: 13年前

Re: 互いに既約な数について

#8

投稿記事 by box » 8年前

x, y, zが互いに既約な数、という条件はいったんわきへどけておいて、
とりあえず
x * x + y * y == z * z
という条件を満たす(x, y, z)の組(ただし、x, y, zはいずれも1~100の整数で、x ≦ yの条件を満たす)を
求めることに専念してみてはどうでしょうか。
x, y, zが互いに既約な数を求めるのはその後で十分。

さて、
z * z = x * x + y * y > x * x より、z > x
z * z = x * x + y * y > y * y より、z > y
x ≦ yを加味して、x ≦ y < z … (1)
さらに、zがたかだか100であることを考え合わせると、x * x + y * yは10000を超えません。 … (2)
(1)(2)を考えに入れれば、ムダな計算がかなり省けそうです。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

nanase

Re: 互いに既約な数について

#9

投稿記事 by nanase » 8年前

わかりました。
考えてみます。

box
記事: 2002
登録日時: 13年前

Re: 互いに既約な数について

#10

投稿記事 by box » 8年前

わざとC以外の言語で書いて煙に巻くなど

コード:

def gcd(m, n)
  m, n = n, m if m < n
  return m if n == 0
  gcd(n, m % n)
end

def kiyaku?(x, y, z)
  return false if gcd(x, y) != 1 || gcd(y, z) != 1 || gcd(z, x) != 1
  true
end

N = 100
1.upto(N) do |x|
  x.upto(N) do |y|
    break if (t = x * x + y * y) > N * N
    (y + 1).upto(N) do |z|
      if t == z * z && kiyaku?(x, y, z)
        printf("%d^2 + %d^2 = %d^2\n", x, y, z)
      end
    end
  end
end
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

閉鎖

“C言語何でも質問掲示板” へ戻る