0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

AOJ の DICE 問題の解法

Last updated at Posted at 2020-12-19

AOJ プログラミング入門 (ITP1) - #11 構造体とクラス(DICE問題)

AIZU ONLINE JUDGE > プログラミング入門 (ITP) > #11 構造体とクラス

ITP1_11_A: DICE I

  • Dice クラスを作成する
    • __init__ メソッドでインスタンス化する
    • move メソッドでサイコロの面を自由に入れ替える
    • roll メソッドで東西南北への動きを実行する
  • サイコロを作って、動かして、面を見る
class Dice():
    def __init__(self, sequence):
        self.sequence = sequence

    def move(self, code):
        return [self.sequence[int(idx)] for idx in str(code)]

    def roll(self, root):
        for d in root:
            if d == 'N': self.sequence = self.move(152304)
            elif d == 'E': self.sequence = self.move(310542)
            elif d == 'S': self.sequence = self.move(402351)
            elif d == 'W': self.sequence = self.move(215043)

dice = Dice(list(map(int, input().split())))
dice.roll(input())
print(dice.sequence[0])

ITP1_11_B: DICE II

  • サイコロの並べ方の候補を全て提示する
    • 6 通りに上面を定める
    • それぞれに対し、鉛直方向の回転を 4 回トライする
  • 上面と前面とが合致しているときの右側の面の目を答える
class Dice():
    def __init__(self, sequence):
        self.sequence = sequence

    def move(self, code):
        return [self.sequence[int(idx)] for idx in str(code)]

    def roll(self, root):
        for d in root:
            if d == 'N': self.sequence = self.move(152304)
            elif d == 'E': self.sequence = self.move(310542)
            elif d == 'S': self.sequence = self.move(402351)
            elif d == 'W': self.sequence = self.move(215043)

seq = list(map(int, input().split()))
for _ in range(int(input())):
    a, b = map(int, input().split())
    for ops in ('', 'N', 'W', 'E', 'S', 'NN'):
        dice = Dice(seq)
        dice.roll(ops)
        for _ in range(4):
            dice.roll('NES')
            if dice.sequence[0] == a and dice.sequence[1] == b:
                print(dice.sequence[2])

ITP1_11_C: DICE III

案 1: NewDice クラスを実装する

  • Dice クラスを継承する
    • candidates でサイコロの並べ方の候補を全て提示する
    • self.candidates で並べ方の全候補を提示する
    • __eq__ メソッドで self.candidates の「最小値」に基づいた == を定義する
  • 二つの NewDice インスタンスの == を判断する
class Dice():
    def __init__(self, sequence):
        self.sequence = sequence

    def move(self, code):
        return [self.sequence[int(idx)] for idx in str(code)]

    def roll(self, ops):
        for op in ops:
            if op == 'N': self.sequence = self.move(152304)
            elif op == 'E': self.sequence = self.move(310542)
            elif op == 'S': self.sequence = self.move(402351)
            elif op == 'W': self.sequence = self.move(215043)

class NewDice(Dice):
    def __init__(self, sequence):
        super().__init__(sequence)
        self.candidates = []
        for ops in ('', 'N', 'W', 'E', 'S', 'NN'):
            dice = Dice(self.sequence)
            dice.roll(ops)
            for _ in range(4):
                dice.roll('NES')
                self.candidates.append(dice.sequence)

    def __eq__(self, other):
        return min(self.candidates) == min(other.candidates)

print('Yes' if NewDice(list(map(int, input().split()))) == NewDice(list(map(int, input().split()))) else 'No')

案2: minimize 関数を実装する

  • minimize 関数を定義する
    • 標準入力を整数値の list に変換する
    • サイコロの並べ方の候補を全て提示し、保存する
    • 「最小」の並べ方を示す list を提示する
  • 2 つのサイコロの「最小の並べ方」が等しければ同じと考える
class Dice():
    def __init__(self, sequence):
        self.sequence = sequence

    def move(self, code):
        return [self.sequence[int(idx)] for idx in str(code)]

    def roll(self, root):
        for d in root:
            if d == 'N': self.sequence = self.move(152304)
            elif d == 'E': self.sequence = self.move(310542)
            elif d == 'S': self.sequence = self.move(402351)
            elif d == 'W': self.sequence = self.move(215043)

def minimize(cin):
    candidates = []
    for ops in ('', 'N', 'W', 'E', 'S', 'NN'):
        dice = Dice(list(map(int, cin.split())))
        dice.roll(ops)
        for _ in range(4):
            dice.roll('NES')
            candidates.append(dice.sequence)
    return min(candidates)

print('Yes' if minimize(input()) == minimize(input()) else 'No')

ITP1_11_D: DICE IV

案 1: NewDice クラスを利用する

class Dice():
    def __init__(self, sequence):
        self.sequence = sequence

    def move(self, code):
        return [self.sequence[int(idx)] for idx in str(code)]

    def roll(self, ops):
        for op in ops:
            if op == 'N': self.sequence = self.move(152304)
            elif op == 'E': self.sequence = self.move(310542)
            elif op == 'S': self.sequence = self.move(402351)
            elif op == 'W': self.sequence = self.move(215043)

class NewDice(Dice):
    def __init__(self, sequence):
        super().__init__(sequence)
        self.candidates = []
        for ops in ('', 'N', 'W', 'E', 'S', 'NN'):
            dice = Dice(self.sequence)
            dice.roll(ops)
            for _ in range(4):
                dice.roll('NES')
                self.candidates.append(dice.sequence)

    def __eq__(self, other):
        return min(self.candidates) == min(other.candidates)

prv = []
for _ in range(int(input())):
    tmp = min(NewDice(list(map(int, input().split()))).candidates)
    if tmp in prv:
        print('No')
        break
    prv.append(tmp)
else:
    print('Yes')

案 2: minimize 関数を利用する

class Dice():
    def __init__(self, sequence):
        self.sequence = sequence

    def move(self, code):
        return [self.sequence[int(idx)] for idx in str(code)]

    def roll(self, ops):
        for op in ops:
            if op == 'N': self.sequence = self.move(152304)
            elif op == 'E': self.sequence = self.move(310542)
            elif op == 'S': self.sequence = self.move(402351)
            elif op == 'W': self.sequence = self.move(215043)

def minimize(cin):
    candidates = []
    for ops in ('', 'N', 'W', 'E', 'S', 'NN'):
        dice = Dice(list(map(int, cin.split())))
        dice.roll(ops)
        for _ in range(4):
            dice.roll('NES')
            candidates.append(dice.sequence)
    return min(candidates)

prv = []
for _ in range(int(input())):
    tmp = minimize(input())
    if tmp in prv:
        print('No')
        break
    prv.append(tmp)
else:
    print('Yes')

まとめ

クラスを実装することで、使い回ししやすいコードを記述することができる。
(関数を定義すると記述量は減らしやすいけど、使い回しには不向きかも)

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?