見出し画像

プログラミング学習記録【23日目】/ AtCoder Beginners Selection -2

ABC081B - Shift only

問題文
黒板にN個の正の数が書かれている。
スヌケくんは、黒板に書かれている整数がすべて偶数であるとき、黒板に書かれている整数すべてを2で割ったものに置き換えることができる。
スヌケくんは最大で何回操作を行うことができるかを出力せよ。

入力された変数は何度も用いることになりそうなので、配列として受け取ることにする。配列を1文字ずつ2で割れるか確認していき、すべて2で割れる場合カウンタを1プラスした上でwhile(judge)とかでjudge = trueの間だけループを回せばいい。

#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
int main()
{
   int N;
   cin >> N;
   vector<int> vec(N);
   rep(i, N)
   {
       cin >> vec.at(i);
   }
   int count = 0;
   bool judge = true;
   while (judge)
   {
       rep(i, N)
       {
           if (vec.at(i) % 2 != 0)
           {
               judge = false;
               break;
           }
           else
           {
               vec.at(i) = vec.at(i) / 2;
           }
           if (i == N - 1)
           {
               count++;
           }
       }
   }
   cout << count << endl;
}

画像1

思いついたとおりにやったので、ifが != になってて、あとから見たら少し歪だが、あっているので良しとする。
今度からは気をつけたい。

ABC087B -Coins

問題文
500円玉をA枚、100円玉をB枚、50円玉をC枚持っている。これらの硬貨から何枚かを選び、ちょうどX円にする方法が何通りあるかを求めよ。同じ種類の硬貨同士は区別できない。

入力はA B C Xと行われる。例えば、2 2 2 100と入力された場合、
・100円玉が1枚
・50円玉が2枚
の2通りであり、2と出力される。
金額の大きい硬貨から順番に選んで、小さい硬貨が何枚選べるかを確認していけばいい。
だが、ここで問題がある。ループする際によく入力されるNが通用するのは、N=0からN=N-1までのN回ループする、という意味であり、今回のように0から入力されたA,B,Cまでループを行いたい場合、1回足りない。よって、A,B,Cをそれぞれ1つ足してからループを行う。

A++;
B++;
C++;

ループ自体は0から始まってくれるので、次のようにループを組んでおくと全通りを確認できる。ループ自体はrepマクロで組んでいる。

rep(i, A){
       rep(j, B){
           rep(k, C){
                sum = 500 * i + 100 * j + 50 * k;

で、これがXと等しいときにカウンタを1つ進めれば良い。
これらを踏まえて組んだソースコードを以下に示す。

#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
int main()
{
   int A, B, C, X;
   cin >> A >> B >> C >> X;
   A++;
   B++;
   C++;

   int sum = 0;
   int count = 0;
   rep(i, A)
   {
       rep(j, B)
       {
           rep(k, C)
           {
               sum = 500 * i + 100 * j + 50 * k;
               if (sum == X)
                   count++;
           }
       }
   }
   cout << count << endl;
}

repマクロの使いやすさが尋常じゃない。
一回一回

for (int i ; i < N; i++)

を書かなくていいのがものすごく楽。

画像2

以上!



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