작년에 이어 올해도 출전할 수 있었다.
출제진이나 스태프가 되지 않는 이상 아마 매년 출전하지 않을까 싶다.
작년에 비해 실력의 최댓값은 크게 늘지 않았지만 평균값은 크게 늘었다고 자부했다.
코딩 테스트 합격을 위해서는 플래티넘 문제를 풀 필요가 없다. 시간제한 안에 골드3 수준의 문제만 무조건 맞출 수 있다면 대부분 합격 하고도 남을 것이다. 그래서 그 부분을 중점적으로 공부했던 것 같다.
수상을 위해서는 2022년 1학기라도 다녔어야 하지만 군대이슈로 인해 22년에는 학교를 다니지 않았어서 어차피 수상권에 들어도 수상을 못하기 때문에 굉장히 가벼운 마음으로 임했다.
역시 A번 부터 그리 간단한 문제는 아니였던 것 같다. 10분 가까이 잡아먹고 2번 정도 틀렸던 것 같다.
사실 맨 처음 생각한대로 그냥 log를 이용해서 풀어주면 되는 문제였지만 뇌절로 인한 이슈가 생각보다 컸다.
https://www.acmicpc.net/problem/27724
from sys import stdin
from math import log2
input=stdin.readline
n,m,k=map(int,input().split())
arr=[i+1 for i in range(n)]
wcnt=0
mx=-1
while n:
mx+=1
n//=2
print(min(int(log2(k))+m,mx))
B번은 보자마자 읽기가 굉장히 싫었지만 그렇게 어려운 문제는 아니였다.
늘 그렇듯 소수의 개수는 그리 많지가 않고, 제곱의 힘은 굉장히 강력하다.
https://www.acmicpc.net/problem/27725
from sys import stdin
from copy import deepcopy
input=stdin.readline
n=int(input())
p=sorted(map(int,input().split()))
k=int(input())
cnt=0
np=deepcopy(p)
dep=0
while True:
nnp=[]
dep+=1
for i in range(len(np)):
cnt+=k//np[i]
if np[i]*p[i]<k:
nnp.append(np[i]*p[i])
np=deepcopy(nnp)
if not nnp:
break
print(cnt)
C번 문제는 풀고나서 보면 굉장히 쉬운 문제지만 대회 당시에는 왜 이렇게 어려웠었는지 모르겠다.
m1,m2,m3 순으로 튜플을 만들어서 딕셔너리의 키값으로 이용해주면 된다.
증명은 못했지만 생각보다 경우의 수가 굉장히 적었다.
https://www.acmicpc.net/problem/27726
from sys import stdin
from collections import defaultdict as dd
input=stdin.readline
def find(x,no):
if x==par[no][x]:
return x
else:
par[no][x]=find(par[no][x],no)
return par[no][x]
def union(a,b,no):
a=find(a,no)
b=find(b,no)
if a<b:
par[no][b]=a
else:
par[no][a]=b
n=int(input())
m1,m2,m3=map(int,input().split())
par=[[i for i in range(n+1)] for i in range(3)]
for i in range(m1):
a,b=map(int,input().split())
union(a,b,0)
for i in range(m2):
a,b=map(int,input().split())
union(a,b,1)
for i in range(m3):
a,b=map(int,input().split())
union(a,b,2)
for i in range(1,n+1):
for j in range(3):
find(i,j)
case=dd(list)
for i in range(1,n+1):
key=(par[0][i],par[1][i],par[2][i])
case[key].append(i)
ans=[]
for i in case:
if len(case[i])>1:
ans.append(case[i])
print(len(ans))
for i in sorted(ans):
print(*i)
D번은 아직도 잘 모르겠다. 잘못된 접근을 어찌어찌 이어가면서 여러가지 예외처리를 해주면서 어거지로 맞췄다.
아이디어는 "정렬이 된 이후로 남은 k는 k//n번 만큼 더 정렬시킬 수 있다"에 집중을 해주었고, 그렇다면 맨 처음 정렬만 어찌어찌 구해주면 답을 구할 수 있을 것이라 생각했다. 그 방법으로는 이제 높이가 같은 것들끼리 합쳐주면서 천천히 올려준다는 느낌으로 구현할 수 있을 것이라 생각했는데 결국 되기는 했지만 정말 더러운 코드가 나왔다.
https://www.acmicpc.net/problem/27727
from sys import stdin
from collections import deque
from heapq import heappop,heappush
input=stdin.readline
# 초기 상태, k가 충분히 커서 모든 수가 같아진 상태
# 일단 무조건 다 채워서 비내림차순을 무조건 만들어주기는 해야함.
n=int(input())
arr=list(map(int,input().split()))
k=int(input())
hq=[]
ch=False
cnt=0
uns=set()
mx=-1
tos=[0]*n
for i in range(n):
if arr[i]>=mx:
mx=arr[i]
else:
tos[i]=mx
uns.add(i)
if uns:
fu=True
else:
fu=False
q=deque(sorted([(arr[i],1,i) for i in range(n)]))
while k and len(q)>1:
now,nowlen,nowidx=q.popleft()
dif=q[0][0]-now
if nowidx in uns:
heappush(hq,(tos[nowidx],nowidx))
if nowlen*(dif)<=k:
k-=nowlen*dif
else:
k=0
break
if not uns:
cnt+=dif
nxt=q.popleft()
if hq and nxt[0]>=hq[0][0]:
_,torem=heappop(hq)
uns.remove(torem)
if not uns:
cnt+=1
q.appendleft((nxt[0],nowlen+1,nxt[2]))
if fu and len(q)==1 and cnt==0:
uns=set()
cnt+=1
if not uns:
cnt+=k//n
print(cnt)
G번은 대회 당일에 아이디어까지는 떠올렸지만 코드까지 짜지는 못했다. 그리고 이 문제는 훈련 나가서까지 내 머릿속을 맴돌며 나를 괴롭혔다.
dist[now]+=dist[bef]-dist[now]-tree[bef][now]*use[now]+tree[bef][now]*(use[bef]-use[now])
이 점화식만 세웠는데 이 점화식을 바탕으로 dfs 1번과 O(N)번의 연산을 통해 최소가 되는 위치를 찾아줄 수 있었다.
여기까진 어찌어찌 구현했지만 정작 이어진 뒤 거리의 합을 구해지 못해서 실전에서는 못풀었던 문제이다.
https://www.acmicpc.net/problem/27730
from sys import stdin,setrecursionlimit
setrecursionlimit(120000)
from collections import defaultdict as dd
from collections import deque
input=stdin.readline
def solve(n):
def getdist(now):
use[now]=1
for i in tree[now]:
if vi[i]==0:
vi[i]=1
getdist(i)
par[i]=now
use[now]+=use[i]
def getminloc():
vi=[0]*(n+1)
vi[1]=1
queue=deque([])
for i in tree[1]:
queue.append((i,1))
while queue:
now,bef=queue.popleft()
vi[now]=1
dist[now]+=dist[bef]-dist[now]-tree[bef][now]*use[now]+tree[bef][now]*(use[bef]-use[now])
use[now]=n
for i in tree[now]:
if vi[i]==0:
queue.append((i,now))
tree=[dd(int) for i in range(n+1)]
dist=[0]*(n+1)
vi=[0]*(n+1)
vi[1]=1
use=[0]*(n+1)
par=[i for i in range(n+1)]
for i in range(n-1):
a,b,c=map(int,input().split())
tree[a][b]=tree[b][a]=c
a=getdist(1)
order=[]
for i in range(1,n):
order.append((use[i+1],i+1))
order.sort()
for usetime,now in order:
dist[par[now]]+=tree[par[now]][now]*usetime
dist[par[now]]+=dist[now]
getminloc()
mn=float('inf')
mnidx=''
for i in range(n):
if dist[i+1]<mn:
mn=dist[i+1]
mnidx=i+1
return mn,mnidx
n=int(input())
mn1,mnidx1=solve(n)
m=int(input())
mn2,mnidx2=solve(m)
print(mnidx1,mnidx2)
print(mn1*m+mn2*n+m*n)
아마 이 문제는 아는사람은 아는 웰논 문제였을 것 같다.
늘 그렇듯 무지성 제출 후 수정으로 인한 패널티를 굉장히 많이 받았다.
결과는 16등으로 마무리 했지만 오랜만에 대회에 대한 욕심이 조금 생겼던 것 같다.
군인이기 때문에 캠을 켜는 코딩테스트의 경우 응시조차 불가능해서 최근에 많이 죽은 감을 되찾을 수 있던 것 같다.
'후기 > 대회' 카테고리의 다른 글
Codeforces Round 937 (Div. 4) (3) | 2024.04.01 |
---|---|
KAUPC 2023 대회 후기 (1) | 2023.07.30 |
Codeforces Round 855 (Div. 3) (버츄얼) (0) | 2023.03.19 |
PS와 장비에 대한 고찰 (제 2회 KAUPC 후기) (2) | 2022.09.17 |
22 현대모비스 알고리즘 경진대회 예선 후기 (0) | 2022.07.04 |