見出し画像

shift onlyの問題

問題の解釈

N個の整数Aを入力し、奇数が含まれていたら0を出力して以降何もしない。入力した整数がすべて偶数なら2で割り、すべての整数が2で割り切れた場合はカウントを増やす。どれかの整数が2で割り切れなくなったらそこでカウントをストップしてカウントの数を出力する。

例1)入力した値が最初から奇数だった場合
N = 3
A = 2   2   3の場合

入力値:
3
2   2   3

出力値:
0

例2)入力した値が最初からすべて偶数だった場合

N = 3, 
A = 2   2   2の場合

入力値:
3
2    2    2

出力値:
1

考え方(僕なりの考え方です):

・入力した整数が偶数か奇数かで処理を分ける。
偶数なら2で割った余りが0となる。
それぞれの整数を2で割った余りをループで足していくと、全て偶数なら0、奇数が1個でも含まれていたら余りは0以上になるので、この結果で条件を分岐する。

// 入力した整数を2で割った余りを計算し、次のループに加算していく
for (int i = 0; i < N; i++) {
   cin >> A[i];
   ans = ans + (A[i] % 2);
 }
 // 入力した整数が偶数か奇数かの判定.もしans > 0なら奇数が含まれているので処理を終了
 if (ans > 0){ 
   cout << 0 << endl;
   } else { // 全て偶数なので次の処理に入る

0以上だったら0を出力して終わり。それ以外は今度は2で割っていき割れた回数をカウントしていく処理に入る。

for文だけだとN個の整数を1回だけ2で割ったら処理を抜けてしまい、2で割り切れなくなるまでループを続けることができないので、for文をwhileで包みました。

2で割るfor文のループが1回終了したら、whileの判定にいきます。1回目のfor文のループが終了したあとにans == 0 の場合は、N個の整数全てが2で割り切れたことを意味するので、またfor文のループに入り、N個の整数のうちどれかの整数が2で割り切れなくなるまでループを続けることができます。


for文のループでN個の整数が全て2で割り切れたらカウントを1回加算したいので、for文のループが終わったら以下のように処理されるようにする。

1回のループの中でA[i]を2で割り、その値を2で割った余りを求める。余りがもし0なら2で割り切れたことを意味するのでUPという変数のカウントを加算する。N個の整数が全て2で割り切れたなら
N = UPであり、入力する整数の個数と割り切れた整数の個数が同じになり、N個の整数がそれぞれ2で割り切れたことを意味する。

→もしN = 4でUPのカウント値が8の場合は、UP / N = 8 / 4 = 2回ループしたことを意味する。whileループに入っている時点で1回は2で割り切れることが確定しているので、N個の整数が全てが何回2で割り切れたかを示すカウント値(=for文のループの回数)を示す変数CTをCT = 1; で事前に初期化しておき、トータル何回2で割れたかを、CT = CT + (UP / N);で計算する。


N = 4, A = 2   2   2   2  の例で考えてみる。

・全て2なのでwhileループに入る。
・for文の中でA / 2 = 1,  1 % 2 は1なので、if文の中のUPはカウントされずループを抜けてCT = CT + (UP / N)が実行される。CT = 1 + (0 / 4) = 1となり、2で割り切れた回数は1回となる。みたいな考え方。

// 2で割った余りが0の間はwhileで処理を継続する
while (ans == 0) {
   for (int i = 0; i < N; i++) {
     A[i] /= 2;
     
     ans = A[i] % 2;
     
     if (ans == 0) {
       UP++;
     }
   }
 }
   CT = CT + (UP / N);
 cout << CT << endl;

以上を踏まえた僕の解答がこちら。ギリギリ正解になったっぽい気もするコードだけど正解できました。

#include <bits/stdc++.h>
using namespace std;
int main() {
 int N;
 int A[200];
 int ans = 0;
 int UP = 0;
 int CT = 1;
 cin >> N;
 for (int i = 0; i < N; i++) {
   cin >> A[i];
   ans = ans + (A[i] % 2);
 }
 if (ans > 0){
   cout << 0 << endl;
   } else { 
   
   while (ans == 0) {
   for (int i = 0; i < N; i++) {
     A[i] /= 2;
     
     ans = A[i] % 2;
     
     if (ans == 0) {
       UP++;
     }
   }
 }
   CT = CT + (UP / N);
 cout << CT << endl;
 }
 return 0;
 }

回答時は消していますが、処理の途中にcoutを入れ込んで、出力値を確認しつつコードを修正していきました。

この記事が気に入ったらサポートをしてみませんか?