###前提・実現したいこと
このページの問題を解きたいです。
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=36
概要としては、
「コラッツ予想とは、任意の整数において、それが偶数ならば2で割り、
奇数だったら3を掛けたものに1を足すという操作を繰り返して行くと、必ず最終的に1になる。つまり、
f(n) = n/2 (nは偶数)
f(n) = 3n+1 (nは奇数)
今、2つの整数の組を入力として与えた時、その範囲内の全ての整数においてこの操作を繰り返し、その中で、1に辿り着くまでにかかった操作の回数が一番多かった時の回数を出力させる。この時、一緒に入力した2整数も出力させる。」
というものです。
例えば入力を1と10とした場合は、1〜10の全ての数字に対して上記の操作を行い、1と、10と、その中で一番手順数が多かった回数、つまり3つの整数を出力させる、ということです。また、入力は2つの整数の組は1セットに限らないそうです。
上記ページの例では、入力を
1 10 100 200 201 210 900 1000
としたとき、出力は
1 10 20 100 200 125 201 210 89 900 1000 174
こうなると書いてあります。
###発生している問題・エラーメッセージ
一度は正しい出力がされたのですが、その後はいくらやっても4行分の出力がされません。
「試したこと」にも書きましたが、indexのインクリメントは正しくされているみたいです。どこがおかしいのでしょう??
また、他のプログラムを書いていてもたまに起こるのですが、その時によって実行結果が変わるというのはどういう仕組み?なのかも合わせて教えてくれると嬉しいです。
###追記
あと、入力を終了させたいときはどうすればいいのでしょう?自分で実行する際はCtrl+Cで強制終了させていましたが、上記のサイトはプログラムを自動採点するため、Ctrl+Cを押させるということはできないと思われるので、プログラムがいつまで経っても終わらない(キーボードからの入力待ちの状態が一生続く)んじゃないかと推測してます。
前は入力は2つの整数が1組だけだと勘違いしていたので、scan.nextIntを2回だけ実行して終わればいいと思っていたのですが、
そうじゃなかったためにwhile(scan.hasNext())を使わざるを得なくなってしまい、入力側(人間)がまだ入力を続けたいのか、そうでないのかを判別させる方法が分からないという問題も出てしまいました。
1 10 100 200 201 210 900 1000 (ここまで入力) 1 10 20 100 200 125 201 210 89
###追記2
fuzzballさんに言われた通り変更したところ、
[0]1 10 20 [1]100 200 125 [2]201 210 89 [3]900 1000 174
と、一旦正しい結果が出力されたのですが、
次のような入力を与えたところ、それ以降に正しく出力されたときと同じ入力を行っても、上記のような不具合が発生するようになりました。
1 10 100 2000 201 210 900 1000
再び正しい出力がされたときは、一旦PCの電源を落とし、再びONにした後でしたが、これは何か関係あるのでしょうか?
そもそも、プログラムを実行し終わった後、もう1回プログラムを実行したところで、2つの事象は別個のものなので、
前の実行時の入力に、あとの実行時の出力が引っ張られるなんて考えられませんが…
###該当のソースコード
java
1import java.util.Scanner; 2import java.util.InputMismatchException; 3 4class Collatz { 5 public static void main (String[] args) { 6 Scanner scan = new Scanner(System.in); 7 int input[][] = new int[100000][2]; //入力の2つの整数組を行列に入れて覚えておく 8 int output[] = new int[100000]; //出力となる手順数の最大値を入れておく 9 int index = 0; //何組目の2つの整数組を見ているかを表す 10 11 while(scan.hasNext()) { 12 try { 13 int countmax = 0; 14 int count = 1; 15 16 input[index][0] = scan.nextInt(); 17 input[index][1] = scan.nextInt(); 18 int a = input[index][0]; 19 int b = input[index][1]; 20 21//以下のループで第1引数の方が小さいことを前提としているため、第2引数の方が小さい場合は値を交換しておく 22 23 if(b<a) { 24 int tmp = b; 25 b = a; 26 a = tmp; 27 } 28 29 for(int n=a; n<=b; n++) { 30 int m = n; 31 while(m!=1) { 32 if(m%2==0) m/=2; 33 else m = 3*m+1; 34 count++; 35 } 36 if(count>countmax) 37 countmax = count; //手順数が暫定最大手順数より多かったら値を更新 38 count = 1; 39 } 40 41 output[index] = countmax; 42 index++; //次の2つの整数組に進む 43 44 } catch(InputMismatchException e) { 45 System.out.println("Input must be type int."); 46 } 47 } 48 49 System.out.println("index="+index); //デバッグ用 50 for(int i=0; i<index; i++) { 51 System.out.println(input[i][0]+" "+input[i][1]+" "+output[i]); //結果の出力 52 } 53 } 54} 55
###試したこと
4行分の出力がされないので、indexのインクリメントが適切な回数行われていないのかな?と思い、
ソースコード下から6行目にindexの値を出力させる行を足しましたが、ちゃんとindex=4と出力されたので、
まるで原因が分かりません。それどころか、この1行を追加しただけで実行結果が以下のように変わってしまい、もう何が起きてるのやらという感じです…
1 10 100 200 201 210 900 1000 (ここまで入力) index=4 1 10 20 100 200 125
indexが4なので、for文でi=0~3の4回分プリントが行われるはずですが、何がおかしいのでしょう?
回答1件
あなたの回答
tips
プレビュー