프로그래밍/문제 풀기

[백준] 처음으로 제대로 된 오픈콘테스트 도전기

jtw7977 2025. 9. 2. 14:22

평소에도 백준 대회를 몇 번 참여해본 적은 있었지만, 대부분은 A번 문제만 가볍게 풀어보고 끝내는 경우가 많았습니다. 그런데 이번에는 시간을 내서 처음부터 끝까지 제대로 도전해보고 싶다는 생각이 들어, 2025 숭고한 연합 알고리즘 경진대회 (Div. 2 + Div. 3) Open Contest에 참여하게 되었습니다.

 

대회는 8월 31일(일요일)에 열렸고, 문제는 A번부터 M번까지 총 13문제가 주어졌습니다. 저는 대회 당일에 A~E번까지 풀었고, 그 이후 문제들이 공개된 오늘은 당시 풀지 못했던 F번 문제를 다시 도전해서 맞출 수 있었습니다.

이번 글에서는 처음으로 ‘제대로’ 도전해 본 오픈콘테스트에서의 경험과, 문제를 풀면서 느낀 점들을 정리해보려고 합니다.

 

 

A번 - 숭고한에 어서오세요 

문제링크 - https://www.acmicpc.net/problem/34236

대회 당일 생각 - 주어지는 A_1, A_2, ..., A_n들은 등차수열임을 알수 있으니까 공차 x를 구하기 위해 A_n항과 A_n-1을 빼서 공차를 구한다음 A_n에 더하면 답이 나오는 간단한 문제라고 생각했다.

정답 코드:

더보기
input()
a,b=map(int,input().split()[-2:])
print(2*b-a)

 

 

B번 - 호참전

문제링크 - https://www.acmicpc.net/problem/34237

대회 당일 생각 - 문제에서 주어진대로 모든경우에 대해서 x<=a, y<=b, a+b<=g만 체크해면 되겠다고 생각했다.

정답코드:

더보기
input=open(0).readline
buffer=[]
n,m=map(int,input().split())
k=[tuple(map(int,input().split())) for _ in range(n)]
for _ in range(m):
    g,x,y=map(int,input().split())
    ans=0
    for a,b in k:
        if x<=a and y<=b and a+b<=g:
            ans+=1
    buffer.append(str(ans))
print('\n'.join(buffer))

 

 

C번 - Find the Fox

문제 링크: https://www.acmicpc.net/problem/34238

대회당일 생각 N*M이 최대 10000이라서 그냥 격자판에서 나이브하게 F를찾고 수평 수직 대각선으로 OX가 있는지 체크를 해주면 되겠다고 생각했다.

정답코드:

더보기
def main():
    n,m=map(int,input().split())
    board=[[*input()]for _ in range(n)]
    ans=0
    for x in range(m):
        for y in range(n):
            if board[y][x]=='F':
                for dx1,dy1,dx2,dy2 in [(x+1,y,x+2,y),(x-1,y,x-2,y),(x,y+1,x,y+2),(x,y-1,x,y-2),(x+1,y+1,x+2,y+2),(x+1,y-1,x+2,y-2),(x-1,y-1,x-2,y-2),(x-1,y+1,x-2,y+2)]:
                    if 0<=dx1<m and 0<=dx2<m and 0<=dy1<n and 0<=dy2<n and board[dy1][dx1]=='O' and board[dy2][dx2]=='X':
                        ans+=1
                
    print(ans)

main()

 

 

D번 - 네모난 순열 찾기 1

문제링크: https://www.acmicpc.net/problem/34231

대회당일 생각: N이 최대 15라서 O(N**4)으로 나이브하게 사각형을 구성한뒤 해당 사각형의 숫자들이 문제에서 주어진 순열의 정의와 맞는지 체크하면 되겠다고 생각해서 풀었다.

정답코드:

더보기
def main():
    n=int(input())
    board=[[*map(int,input().split())]for _ in range(n)]
    ans=0
    for x1 in range(n):
        for y1 in range(n):
            for x2 in range(x1,n):
                for y2 in range(y1,n):
                    ans+=check(board,x1,y1,x2,y2)
    print(ans)

def check(board,sx,sy,ex,ey):
    nums=set()
    for i in range(sx,ex+1):
        for j in range(sy,ey+1):
            num=board[j][i]
            if num in nums:
                return 0
            nums.add(num)
    for k in range(1,(abs(sx-ex)+1)*(abs(sy-ey)+1)+1):
        if k not in nums:
            return 0
    return 1
    
main()

 

 

E번 - 현대모비스 부품 조립

문제 링크: https://www.acmicpc.net/problem/34225

대회당일 생각: 효율이 높은것을 가져가는게 항상 유리하고 그후부터는 효율이 낮을것을 가져갈지 말지 체크하면서 A_max+A_min+sum(A)가 최대일때가 답이라고 생각했다.

대회당일 실수: 

1. 한번 max가 갱신되면 다시는 갱신이 되지 않을 듯 -> x 

7 5 2 1 1 1 1 1 가 반례였다.

2. 처음의 A_max+A_min+sum(A)는 A_max * 3인데 *3을 안해서 틀렸었다.

정답 코드:

더보기
def main():
    input()
    max_a=None
    suma=0
    ans=[]
    max_sum=0
    idx=0
    ridx=0
    for i,a in sorted(enumerate(map(int,input().split()),1),key=lambda x:-x[1]):
        if max_a==None:
            max_a=a
            suma=a
            max_sum=a*3
        else:
            t=max_a+2*a+suma
            if max_sum<t:
                max_sum=t
                ridx=idx
            suma+=a
        ans.append(i)
        idx+=1
    print(len(ans[:ridx+1]))
    print(*ans[:ridx+1])
main()

 

 

F번 - 네모난 순열 찾기 2

문제링크: https://www.acmicpc.net/problem/34232

대회당일 생각: 사각형안에 1부터 사각형 크기만큼 다 있으려면 크기가 max값과 같아야 하지 않을까? 근데 어떻게 사각형을 관리하지...?

> 결국 이 문제는 풀지 못하였다.

대회후 에디토리얼을 보고 깨달은 점: 1부터 N**2크기만큼 각 좌표를 미리 저장한다음 사각형의 최댓값을 k라고 하면 사각형을 k를 포함시킬수 있도록 업데이트 해준다음 사각형의 크기가 k과 같으면 경우의 수를 한개 올리면 되겠구나!

정답 코드:

더보기
def main():
    input=open(0).readline
    n=int(input())
    nums=[None]*(n**2+1)
    board=[]
    for y in range(n):
        b=[*map(int,input().split())]
        for x in range(n):
            nums[b[x]]=(x,y)
    x1,y1=nums[1]
    x2,y2=nums[1]
    ans=0
    for k in range(1,n**2+1):
        x,y=nums[k]
        x1,y1=min(x1,x),min(y1,y)
        x2,y2=max(x2,x),max(y2,y)
        if k==(x2-x1+1)*(y2-y1+1):
            ans+=1
    print(ans)
main()

 

 

후기 & 느낀점


처음으로 제대로 도전한 대회였는데, 그래도 solve.ac 기준 실버 하위 난이도의 문제들은 대부분 풀 수 있었다는 점에서 나름 의미 있는 경험이었습니다. 특히 대회 당일에는 풀지 못했던 F번 문제를 대회가 끝난 뒤 다시 도전해서 맞출 수 있었던 것이 가장 뿌듯했습니다.

최종 결과는 17등이었는데, 첫 도전 치고는 만족스럽기도 하고, 동시에 아쉬움도 남는 성적이었습니다. 문제를 풀 때 태그에 의존하는 습관이 있는데, 이런 부분을 줄이고 스스로 접근법을 더 고민한다면 앞으로는 더 좋은 성적을 낼 수 있을 것 같다는 생각이 들었습니다.

이번 대회는 Div.2 + Div.3이었던 만큼 난이도도 적당했고, 문제 구성도 흥미로웠습니다. 무엇보다 대회를 준비하고 운영해주신 출제진과 검수진 분들 덕분에 즐겁게 참여할 수 있었습니다.

다음에는 더 많이 공부하고, 더 다양한 문제에 도전해보고 싶습니다. 또한 아직 손대지 못한 문제들도 차근차근 풀어보면서 실력을 다져가야겠다고 다짐했습니다.

17등