

> x, y, n を正の整数として、 1/x+1/y=1/n, x ≤ yを満たす (x, y, n) を考える。例えば、n = 4 のとき、3
> 個の異なる解 (x, y, 4) がある。具体的には、1/5+1/20=1/4→ (x, y, n) = (5, 20, 4)
> 1/6+1/12=1/4→ (x, y, n) = (6, 12, 4) 1/8+1/8=1/4→ (x, y, n) = (8, 8, 4) の 3
> 個である。解の個数が 200 を超える最小の n を求めるプログラムを作成し、その値を求めなさい。

自分でここまで書いてみましたがこれ以上はわかりません。どこをどう直すべきか教えてください。

[code]

    public class Main {
        public static void main(String[] args) throws Exception {
          int n=1;
          int temp = 0;
          while(true){
            while(temp<=n){
             int x = new java.util.Random().nextInt(n) + 1;
             int y = new java.util.Random().nextInt(n) + 1;
             int sum = 0;
              temp = 0;
             if(1/x + 1/y == 1/temp && x <= y ){
               sum = sum + 1;
              if(sum > 200){
                break;
              }
             temp++;
           }
           n++;
          }
        }
        System.out.println(n);
      }
    }
    
[/code]

**エラー：**

[code]

    Main.java:21: error: unreachable statement
        System.out.println(n);
        ^
    1 error
    
[/code]


CC BY-SA 4.0
2022-11-11T14:07:46.757
92168
2022-11-12T05:14:45.493
2022-11-11T15:19:02.580
3060
55336
question
java
javaで以下のプログラムを作りたいのですがわかりません。教えてください。


とりあえず３箇所おかしいところがあります

  1. まずエラーの原因は while(true) の次にある System.out.println に到達できないというエラーです  
唯一ある break は１つ外のループを抜けるだけなので  
`while(temp<=n){` はぬけますが外側の `while(true){` は抜けません  
なので絶対に抜けないループの次に処理をかいたせいでエラーになっています  
外側のループにラベルをつけて `break ラベル名` とかけば外側のループまで抜けることができます

  2. int 型の割り算は切り捨てです  
`if(1/x + 1/y == 1/temp ` は x, y, temp が 2 以上だと両辺 0 になって必ず成立してしまいます

  3. そもそも答えの決まってる問題を解くのに乱数を使うのはおかしいかも  
乱数だと同じ x y の組み合わせも出現してしまうので  
1 つでも解があればその組み合わせが200回でるまで繰り返してるだけになります  
例えば n=4 のときループ１回目で(x, y, n) = (5, 20, 4) がみつかったとすると次のループで (x, y, n) = (5, 20,
4) がまた見つかることも有りえます  
その場合同じ解でカウントが 2 増えることになります  
なので必ず違う x y の組み合わせすべてをループで回して sum を数える必要があります

ただ実際には x だけループを回せば y は x と n が決まってれば計算可能ですよね  
1/x + 1/y = 1/n の式から y = xn / (x - n) と求まります  
この y が整数かつ y >= x となった場合だけカウントすればいいわけです

[code]

    public class Main {
      public static void main(String[] args) throws Exception {
        int n=1;
    
        L: // 多重ループ内側から抜けるためのラベル
        while(true){
          /*
            x の下限は n + 1 (1/n = 1/x + 1/y > 1/x)  
            : 足して 1/100 になるには両方 1/101 以下じゃないと片方で超えてしまう
    
            x の上限は 2n (1/n = 1/x + 1/y <= 1/x + 1/x = 2/x) 
            : 足して 1/100 になるにはどちらかは 1/200 以上じゃないと 1/201 + 1/201 では 1/100に届かない
    
            つまり x は n+1 ～ 2n までループすればいい
            ちな x <= 2n なら自動的に y >= 2n >= x (1/x + 1/y >= 1/2n + 1/y = n)
            なので y >= x はチェックしなくても 1/5+1/20=1/4  1/20+1/5=1/4　のように x y 入れ替えたものが両方カウントされることはない
          */
          int sum = 0;
          for(int x = n + 1; x <= n * 2; x++) {
            int y = x * n / (x - n);
            if(x * n % (x - n) == 0) { // xn / (x - n) の余りが 0 => 整数
              sum = sum + 1;
              if(sum > 200)
                break L; // ラベルなしだと内側のループしか抜けないので外側のループラベルをつけて抜ける
    
              // n = 4 のときだけデバッグ表示
              if(n == 4) System.out.println("1/" + x + " + 1/" + y + " = 1/" + n + " (sum=" + sum + ")");
            }
          }
          n++;
        }
        System.out.println(n);
      }
    }
    
[/code]


CC BY-SA 4.0
2022-11-11T20:28:12.783
92170
2022-11-12T05:14:45.493
2022-11-12T05:14:45.493
92168
answer