実現したいこと
AtCoderの問題に関するプログラムを作ったが,不正解で,どこが間違っているのかを知り,正解にすること.
前提
高校二年生です.
AtCoderで以下のような問題を解いています.
黒板に N 個の正の整数 A_1,...A_nが書かれています.
すぬけ君は,黒板に書かれている整数がすべて偶数であるとき,次の操作を行うことができます.
・黒板に書かれている整数すべてを,2 で割ったものに置き換える.
すぬけ君は最大で何回操作を行うことができるかを求めてください.
実行例
入力
3
8 12 40
出力
2
上記の実行例は8,12,40が二回2で割れたことを示しています.
この問題に対して自分なりにC++言語でプログラムを作ってみて,自分のpcの端末で
g++で実行してみたところ,実行例と同じような結果が得られました.なのでAtCoder
で提出したのですが不正解と出てしまい,そのあとも考えてみたのですが,全然わかりません.
なので,どこが違っているのかを知りたいので,どなたかに教えていただきたいです.
該当のソースコード
C++
1#include <iostream> 2 3 4using namespace std; 5 6int main(){ 7 int N; 8 cin >> N; 9 10 int a; 11 int A[210]; 12 for (int i = 0; i < N; i++) cin >> A[i]; 13 14 int total = 0; 15 while(1){ 16 for (int i = 0; i < N; i++){ 17 if(A[i] % 2 == 0) 18 A[i] = A[i] / 2; 19 else 20 a = 1; 21 } 22 23 if (a == 1) 24 break; 25 26 else 27 total++; 28 } 29 30 cout << total << endl; 31return 0; 32} 33
endlは改行文字を出力するのでその分が答えとして余計で不正解なんじゃないでしょうか?
endlがなかったらどうなりますか?
for ループの内部で、偶数でない場合には即座にループ処理を終了する必要があります。また、a が初期化されていません。
> 実行例と同じような結果が得られました.
「2」が出力された、ということですか?当方が質問のコードを試したところ、「0」が出力されました。
このアルゴリズムだとそもそも時間オーバーしますね。
もう一度最初から考え直しましょう。
Zuishinさん タイムオーバーの件に関してですが,今回上記で不正解となったプログラムは11msで正解となったプログラムも11msなので,タイムオーバーではないと思われます.
補足:11msは実行時間です.
while で無限ループするかと思いましたが、よく見ると break はループ中にありますね。
それにしてもかなり独特なインデントの使い方です。
C言語とC++言語を勉強して一年たっていなく,だれにでもわかりやすいきれいなコードを書きたいのですが,なかなか難しく...四苦八苦している状況です.わかりやすいコードが書けるように精進します.
一応補足しておきますと、Linux OS(おそらく、UNIX 系 OS 全般)では初期化していない変数 a の値が 1 になる場合があります。実際、ランダム生成した数値列を入力として、a を初期化していないバージョンを 100 回連続で実行すると 20〜35 回程度は a の値が 1 になります。同一のプログラムを短時間内に(ミリ秒のオーダーはモダンな CPU では「かなり長い」というべきですが…)連続実行すると、プロセス空間を再利用(reuse)する可能性が高くなるということかと思います。正確を期すのであれば、変数 a の物理メモリアドレス(仮想メモリアドレスではなく)を調べることになりますが、面倒くさいのでもう寝ます。おやすみなさい。

回答2件
あなたの回答
tips
プレビュー