結果

問題 No.5017 Tool-assisted Shooting
ユーザー すぎぱも(sugipamo)
提出日時 2023-07-16 17:56:05
言語 Python3
(3.13.1 + numpy 2.2.1 + scipy 1.14.1)
結果
AC  
実行時間 169 ms / 2,000 ms
コード長 4,817 bytes
コンパイル時間 617 ms
コンパイル使用メモリ 11,224 KB
実行使用メモリ 25,260 KB
スコア 2,088,913
平均クエリ数 979.21
最終ジャッジ日時 2023-07-16 17:56:28
合計ジャッジ時間 18,605 ms
ジャッジサーバーID
(参考情報)
judge12 / judge13
純コード判定しない問題か言語
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
other AC * 100
権限があれば一括ダウンロードができます

ソースコード

diff #

# import time
# timer = time.perf_counter()

output = []


class enemy():
    def __init__(self, hp, power, pos):
        self.hp = hp + 1
        self.power = power
        self.point = hp
        self.exp = power
        self.pos = [pos, 60]

    def move(self, p):
        self.pos[1] -= 1
        if p.pos[0] == self.pos[0] and p.pos[1] == self.pos[1]:
            return False
        return True

    def state(self):
        print("HP:{} POWER:{} POS:{}".format(self.hp, self.power, self.pos))


class enemys():
    def __init__(self):
        self.enemys = []
        self.deleted = []
        from collections import deque
        self.canattacks = [deque() for _ in range(25)]

    def states(self):
        for e in self.enemys:
            e.state()

    def expect_defeat_values(self, p):
        # ret = []
        min_ = ([], 1 << 60)
        for i in range(25):
            if not self.canattacks[i]:
                continue
            i = self.canattacks[i][0]
            e = self.enemys[i]
            t = abs(p.pos[0] - e.pos[0]) + int(e.hp / p.level)
            if e.hp % p.level != 0:
                t += 1

            t += 1

            if t >= e.pos[1]:
                continue

            if min_[1] <= t:
                continue

            if p.pos[0] < e.pos[0]:
                que = [1] * (e.pos[0] - p.pos[0])
            else:
                que = [-1] * (p.pos[0] - e.pos[0])

            if e.pos[1] < len(que):
                continue

            isok = True
            pos = [p.pos[0], p.pos[1]]
            for d in que:
                pos[1] += 1
                pos[0] += d
                if pos[0] < 0:
                    pos[0] += 25
                pos[0] = pos[0] % 25

                for c in self.canattacks[pos[0]]:
                    e_ = self.enemys[c]
                    if abs(e_.pos[1] - pos[1]) <= 2:
                        isok = False
                        break

                if not isok:
                    break

            if isok:
                min_ = (que, t)
            # ret.append((que, v))

        return min_

    def add(self, enemy):
        if self.deleted:
            i = self.deleted.pop()
        else:
            i = len(self.enemys)
            self.enemys.append([])

        self.enemys[i] = enemy
        self.canattacks[enemy.pos[0]].append(i)

    def defeat(self, i):
        for j in range(25):
            if not self.canattacks[j]:
                continue
            if i == self.canattacks[j][0]:
                self.canattacks[j].popleft()
                self.deleted.append(i)
                return

    def move(self, p):
        delque = []
        for canattack in self.canattacks:
            for i in canattack:
                e = self.enemys[i]
                b = e.move(p)
                if not b:
                    return False
                if e.pos[1] < 1:
                    delque.append(i)
        for i in delque:
            self.canattacks[self.enemys[i].pos[0]].popleft()
            self.deleted.append(i)
        return True


class player():
    def __init__(self):
        self.pos = [12, 0]
        self.level = 1
        self.exp = 0
        self.point = 0

    def states(self):
        print("POS:{} LEVEL:{} EXP:{} POINT:{}".format(
            self.pos, self.level, self.exp, self.point))

    def attack(self, enemys: enemys):
        if not enemys.canattacks[self.pos[0]]:
            return

        i = enemys.canattacks[self.pos[0]][0]
        e = enemys.enemys[i]
        e.hp -= self.level
        if e.hp <= 0:
            enemys.defeat(i)
            self.exp += e.exp
            self.level = 1 + int(self.exp / 100)
            self.point += e.point

    def move(self, dir, enemys: enemys):
        dstr = "S"
        if dir == -1:
            dstr = "L"
        if dir == 1:
            dstr = "R"
        output.append(dstr)
        print(dstr)

        self.pos[0] += dir
        if self.pos[0] < 0:
            self.pos[0] + 25
        self.pos[0] = self.pos[0] % 25

        if enemys.canattacks[self.pos[0]]:
            if enemys.enemys[enemys.canattacks[self.pos[0]][0]].pos[1] == 0:
                return False
        return True


es = enemys()
p = player()

while len(output) < 1000:
    for i in range(int(input())):
        inp = input().split()
        if int(inp[0]) == -1:
            break
        es.add(enemy(*map(int, inp)))

    que, _ = es.expect_defeat_values(p)

    p.attack(es)

    m = 0
    if que:
        m = que.pop()
    if not p.move(m, es):
        break
    if not es.move(p):
        break


# es.states()
# p.states()


# def text(output):
#     import os
#     os.remove("output.txt")
#     with open("output.txt", "w") as o:
#         for out in output:
#             print(out, file=o)


# text(output)
0