プログラミング学習記録【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;
}
思いついたとおりにやったので、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++)
を書かなくていいのがものすごく楽。
以上!
この記事が気に入ったらサポートをしてみませんか?