AtCoderに登録したら解くべき精選過去問10問をクラスで解いてみた

# はじめに


[AtCoder に登録したら次にやること ～ これだけ解けば十分闘える！過去問精選 10 問 ～](https://qiita.com/drken/items/fd4e5e3630d0f5859067) をクラス（言語はPython）で解いてみました。
この問題のPythonを用いた一般的な解法は[こちらの記事](https://qiita.com/KoyanagiHitoshi/items/c5e82841b8d0f750851d)をご参考ください。

##### 本記事執筆のモチベーション
- Pythonを学び始めた方に嫌煙されがちな「クラス」のハードルを下げたい

### 第1問 [ABC 086 A - Product](https://beta.atcoder.jp/contests/abc086/tasks/abc086_a)
```python
class Product:
    def __init__(self, a, b):
        self.a = a
        self.b = b

    def is_even(self):
        return (self.a * self.b) % 2 == 0

    def is_odd(self):
        return not self.is_even()

    def check_product(self):
        if self.is_even():
            return "Even"
        else:
            return "Odd"

def main():
    a, b = map(int, input().split())
    product = Product(a, b)
    print(product.check_product())

if __name__ == "__main__":
    main()

```


### 第2問 [ABC 081 A - Placing Marbles](https://atcoder.jp/contests/abs/tasks/abc081_a)
```python
class Marbles:
    def __init__(self, s):
        self.s = s

    def count_placed_marbles(self):
        return self.s.count("1")

def main():
    s = input().strip()
    marbles = Marbles(s)
    print(marbles.count_placed_marbles())

if __name__ == "__main__":
    main()

```

### 第3問 [ABC 081 B - Shift Only](https://beta.atcoder.jp/contests/abc081/tasks/abc081_b)
```python
class ShiftOnly:
    def __init__(self, n, numbers):
        self.n = n
        self.numbers = numbers

    def count_operations(self):
        count = 0
        while all(number % 2 == 0 for number in self.numbers):
            self.numbers = [number // 2 for number in self.numbers]
            count += 1
        return count

def main():
    n = int(input().strip())
    numbers = list(map(int, input().split()))
    shift_only = ShiftOnly(n, numbers)
    print(shift_only.count_operations())

if __name__ == "__main__":
    main()

```

### 第4問 [ABC 087 B - Coins](https://beta.atcoder.jp/contests/abc087/tasks/abc087_b)
```python
class Coins:
    def __init__(self, a, b, c, x):
        self.a = a
        self.b = b
        self.c = c
        self.x = x

    def count_combinations(self):
        count = 0
        for a_count in range(self.a + 1):
            for b_count in range(self.b + 1):
                for c_count in range(self.c + 1):
                    total = 500 * a_count + 100 * b_count + 50 * c_count
                    if total == self.x:
                        count += 1
        return count

def main():
    a = int(input().strip())
    b = int(input().strip())
    c = int(input().strip())
    x = int(input().strip())
    coins = Coins(a, b, c, x)
    print(coins.count_combinations())

if __name__ == "__main__":
    main()

```

### 第5問 [ABC 083 B - Some Sums](https://beta.atcoder.jp/contests/abc083/tasks/abc083_b)
```python
class SomeSums:
    def __init__(self, n, a, b):
        self.n = n
        self.a = a
        self.b = b

    def sum_of_digits(self, number):
        return sum(map(int, str(number)))

    def calculate_sum(self):
        total = 0
        for i in range(1, self.n + 1):
            digit_sum = self.sum_of_digits(i)
            if self.a <= digit_sum <= self.b:
                total += i
        return total

def main():
    n, a, b = map(int, input().split())
    some_sums = SomeSums(n, a, b)
    print(some_sums.calculate_sum())

if __name__ == "__main__":
    main()

```

### 第6問 [ABC 088 B - Card Game for Two](https://beta.atcoder.jp/contests/abc088/tasks/abc088_b)
```python
class CardGameForTwo:
    def __init__(self, n, cards):
        self.n = n
        self.cards = cards

    def calculate_score_difference(self):
        sorted_cards = sorted(self.cards, reverse=True)
        alice_score = sum(sorted_cards[::2])
        bob_score = sum(sorted_cards[1::2])
        return alice_score - bob_score

def main():
    n = int(input())
    cards = list(map(int, input().split()))
    card_game = CardGameForTwo(n, cards)
    print(card_game.calculate_score_difference())

if __name__ == "__main__":
    main()

```

### 第7問 [ABC 085 B - Kagami Mochi](https://beta.atcoder.jp/contests/abc085/tasks/abc085_b)
```python
class KagamiMochi:
    def __init__(self, n, diameters):
        self.n = n
        self.diameters = diameters

    def max_layers(self):
        unique_diameters = set(self.diameters)
        return len(unique_diameters)

def main():
    n = int(input())
    diameters = [int(input()) for _ in range(n)]
    kagami_mochi = KagamiMochi(n, diameters)
    print(kagami_mochi.max_layers())

if __name__ == "__main__":
    main()

```


### 第8問 [ABC 085 C - Otoshidama](https://beta.atcoder.jp/contests/abc085/tasks/abc085_c)
```python
class Otoshidama:
    def __init__(self, n, y):
        self.n = n
        self.y = y

    def find_combination(self):
        for x in range(self.n + 1):
            for y in range(self.n - x + 1):
                z = self.n - x - y
                total = 10000 * x + 5000 * y + 1000 * z
                if total == self.y:
                    return x, y, z
        return -1, -1, -1

def main():
    n, y = map(int, input().split())
    otoshidama = Otoshidama(n, y)
    x, y, z = otoshidama.find_combination()
    print(f"{x} {y} {z}")

if __name__ == "__main__":
    main()

```

### 第9問 [ABC 049 C - Daydream](https://beta.atcoder.jp/contests/abc049/tasks/arc065_a)
```python
class Daydream:
    def __init__(self, s):
        self.s = s
        self.words = ["dream", "dreamer", "erase", "eraser"]

    def is_possible(self):
        reversed_s = self.s[::-1]
        reversed_words = [word[::-1] for word in self.words]

        index = 0
        while index < len(reversed_s):
            for word in reversed_words:
                if reversed_s.startswith(word, index):
                    index += len(word)
                    break
            else:
                return False

        return True

def main():
    s = input().strip()
    daydream = Daydream(s)
    result = daydream.is_possible()
    print("YES" if result else "NO")

if __name__ == "__main__":
    main()

```

### 第10問 [ABC 086 C -Traveling](https://beta.atcoder.jp/contests/abc086/tasks/arc089_a)
```python
class Traveling:
    def __init__(self, n, plan):
        self.n = n
        self.plan = plan

    def is_possible(self):
        prev_t, prev_x, prev_y = 0, 0, 0

        for t, x, y in self.plan:
            dt = t - prev_t
            dist = abs(x - prev_x) + abs(y - prev_y)

            if dt < dist or (dt - dist) % 2 != 0:
                return False

            prev_t, prev_x, prev_y = t, x, y

        return True

def main():
    n = int(input())
    plan = [tuple(map(int, input().split())) for _ in range(n)]

    traveling = Traveling(n, plan)
    result = traveling.is_possible()

    print("Yes" if result else "No")

if __name__ == "__main__":
    main()

```


# 終わりに
クラスは嫌煙されがちですが、使ってみると意外と簡単です。習うより慣れよだと考えています。
ちなみに、スピードが重視される競技プログラミングでは、クラスを用いることは適していないです。ただし、一般的なプログラミングでは、クラスを用いることでコードの保守性や可読性が向上し、開発効率が高まります。この記事が、競技プログラミング以外のプログラミング状況でクラスを適切に活用するための学習リソースとなれば幸いです。