[BOJ 10775]空港(Python)
7239 ワード
質問する
リンク
に答える
最初は、飛行機を中心とした1番から入力したgi番までのすべての関門を探索し、飛行機を空きドアの1つに停泊しようとした.時間複雑度はO(GP)
であり,100,000 x 100,000 = 10,000,000,000
時間を超えると予想され,別の方法で解くことを試みた.
しかし、私は方法が思いつかなくて、私は他の人の解答を参考にしてunion-find
アルゴリズムを使っていることに気づいた.(時間の複雑さが大幅に低下)(union-find
アルゴリズムは知っていたのですが、なぜこの問題に使うのか分かりません.反省しなければなりません…)
注意:他人の解答
飛行機をドッキングするときは、ドッキング可能な最大数の搭乗口に常に対応しなければならない.最大ドック数を求める必要があるからです.例:
(Ex)
1号機がゲート1にドッキングした場合、2号機はいずれのハッチにもドッキングできません.最大1台しかドッキングできません.
しかし、1号機がゲート2に停泊すれば、2号機はゲート1に停泊でき、最大2機まで停泊できる.(最高価格)
問題で与えられた最初の例の入力で簡単に説明しようとします.理解していなければ、上の参考リンクに入るとわかりやすく理解できます.
(Ex)
上の図のように、Gate 3とGate 4が接続されています.これは(parents[4] = 3
)ゲイト4号がドックステーションであり、他の飛行機はドックステーションに入れないと考えられることを意味する.
与えられた例の入力とは異なり、次のAirplaneの入力が4の場合、Gate 4はドッキングステーションであるため、Gate 3上にドッキングする必要がある.(最大ドッキングステーション数を取得するには、ドッキング可能な残りの最大ゲートにドッキングする必要があります.)ここでGate 3はドッキングする飛行機がないのでドッキング可能(parents[3] = 3
).
つまり、parents[x] == x
であれば、x番ゲートに対向することができる.ただし、x=0を除く.parents[x] != x
の場合、x番ゲートウェイに接続できないため、1番~(x-1)番ゲートウェイに空きゲートウェイを見つけなければなりません.左隣のドアを確認すればいいです.parents[x] = 0
であれば、飛行機はどのドアにも入ることができず、空港は閉鎖され、どの飛行機も到着できずに終了します.(これがノード0号(Gate 0号)を作成した理由です.)
この方法でドックマークを作って問題を解くといいです.
コード#コード# import sys
# 비행기를 도킹할 때 항상 넣을 수 있는 가장 큰 수의 게이트에 도킹해야함. (최대 도킹 수를 구해야하므로)
input = sys.stdin.readline
G = int(input())
P = int(input())
docking = list(int(input()) for _ in range(P))
parents = [i for i in range(G + 1)]
ans = 0
def find(parent, x):
if parent[x] == x:
return x
parent[x] = find(parent, parent[x])
return parent[x] # 경로압축
def union(parent, a, b):
rootA = find(parent, a)
rootB = find(parent, b)
if rootA < rootB:
parent[rootB] = rootA
else:
parent[rootA] = rootB
for d in docking:
root = find(parents, d)
# 0일 때 끝나는 이유 -> 비행기가 어느 게이트에도 도킹할 수 없으면 공항 폐쇄되고,
# 이후 어떤 비행기도 도착할 수 없기 때문에 더이상 탐색할 필요가 X
if root == 0:
break
# union(parents, d, d - 1) --> (Ex) 2-3 연결되어있고 1은 비어있음. d=3이면 1-2-3 연결되어야 하는데
# 3의 부모인 2와 1을 연결해야하는데, 위 코드는 3과 2를 연결해서 오류발생!
union(parents, root, root - 1)
ans += 1
print(ans)
Reference
この問題について([BOJ 10775]空港(Python)), 我々は、より多くの情報をここで見つけました
https://velog.io/@kimdukbae/BOJ-10775-공항-Python
テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol
最初は、飛行機を中心とした1番から入力したgi番までのすべての関門を探索し、飛行機を空きドアの1つに停泊しようとした.時間複雑度は
O(GP)
であり,100,000 x 100,000 = 10,000,000,000
時間を超えると予想され,別の方法で解くことを試みた.しかし、私は方法が思いつかなくて、私は他の人の解答を参考にして
union-find
アルゴリズムを使っていることに気づいた.(時間の複雑さが大幅に低下)(union-find
アルゴリズムは知っていたのですが、なぜこの問題に使うのか分かりません.反省しなければなりません…)注意:他人の解答
飛行機をドッキングするときは、ドッキング可能な最大数の搭乗口に常に対応しなければならない.最大ドック数を求める必要があるからです.例:
(Ex)
1号機がゲート1にドッキングした場合、2号機はいずれのハッチにもドッキングできません.最大1台しかドッキングできません.
しかし、1号機がゲート2に停泊すれば、2号機はゲート1に停泊でき、最大2機まで停泊できる.(最高価格)
問題で与えられた最初の例の入力で簡単に説明しようとします.理解していなければ、上の参考リンクに入るとわかりやすく理解できます.
(Ex)
上の図のように、Gate 3とGate 4が接続されています.これは(
parents[4] = 3
)ゲイト4号がドックステーションであり、他の飛行機はドックステーションに入れないと考えられることを意味する.与えられた例の入力とは異なり、次のAirplaneの入力が4の場合、Gate 4はドッキングステーションであるため、Gate 3上にドッキングする必要がある.(最大ドッキングステーション数を取得するには、ドッキング可能な残りの最大ゲートにドッキングする必要があります.)ここでGate 3はドッキングする飛行機がないのでドッキング可能(
parents[3] = 3
).つまり、
parents[x] == x
であれば、x番ゲートに対向することができる.ただし、x=0を除く.parents[x] != x
の場合、x番ゲートウェイに接続できないため、1番~(x-1)番ゲートウェイに空きゲートウェイを見つけなければなりません.左隣のドアを確認すればいいです.parents[x] = 0
であれば、飛行機はどのドアにも入ることができず、空港は閉鎖され、どの飛行機も到着できずに終了します.(これがノード0号(Gate 0号)を作成した理由です.)この方法でドックマークを作って問題を解くといいです.
コード#コード# import sys
# 비행기를 도킹할 때 항상 넣을 수 있는 가장 큰 수의 게이트에 도킹해야함. (최대 도킹 수를 구해야하므로)
input = sys.stdin.readline
G = int(input())
P = int(input())
docking = list(int(input()) for _ in range(P))
parents = [i for i in range(G + 1)]
ans = 0
def find(parent, x):
if parent[x] == x:
return x
parent[x] = find(parent, parent[x])
return parent[x] # 경로압축
def union(parent, a, b):
rootA = find(parent, a)
rootB = find(parent, b)
if rootA < rootB:
parent[rootB] = rootA
else:
parent[rootA] = rootB
for d in docking:
root = find(parents, d)
# 0일 때 끝나는 이유 -> 비행기가 어느 게이트에도 도킹할 수 없으면 공항 폐쇄되고,
# 이후 어떤 비행기도 도착할 수 없기 때문에 더이상 탐색할 필요가 X
if root == 0:
break
# union(parents, d, d - 1) --> (Ex) 2-3 연결되어있고 1은 비어있음. d=3이면 1-2-3 연결되어야 하는데
# 3의 부모인 2와 1을 연결해야하는데, 위 코드는 3과 2를 연결해서 오류발생!
union(parents, root, root - 1)
ans += 1
print(ans)
Reference
この問題について([BOJ 10775]空港(Python)), 我々は、より多くの情報をここで見つけました
https://velog.io/@kimdukbae/BOJ-10775-공항-Python
テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol
import sys
# 비행기를 도킹할 때 항상 넣을 수 있는 가장 큰 수의 게이트에 도킹해야함. (최대 도킹 수를 구해야하므로)
input = sys.stdin.readline
G = int(input())
P = int(input())
docking = list(int(input()) for _ in range(P))
parents = [i for i in range(G + 1)]
ans = 0
def find(parent, x):
if parent[x] == x:
return x
parent[x] = find(parent, parent[x])
return parent[x] # 경로압축
def union(parent, a, b):
rootA = find(parent, a)
rootB = find(parent, b)
if rootA < rootB:
parent[rootB] = rootA
else:
parent[rootA] = rootB
for d in docking:
root = find(parents, d)
# 0일 때 끝나는 이유 -> 비행기가 어느 게이트에도 도킹할 수 없으면 공항 폐쇄되고,
# 이후 어떤 비행기도 도착할 수 없기 때문에 더이상 탐색할 필요가 X
if root == 0:
break
# union(parents, d, d - 1) --> (Ex) 2-3 연결되어있고 1은 비어있음. d=3이면 1-2-3 연결되어야 하는데
# 3의 부모인 2와 1을 연결해야하는데, 위 코드는 3과 2를 연결해서 오류발생!
union(parents, root, root - 1)
ans += 1
print(ans)
Reference
この問題について([BOJ 10775]空港(Python)), 我々は、より多くの情報をここで見つけました https://velog.io/@kimdukbae/BOJ-10775-공항-Pythonテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol