NYPC 문제풀이

개요

NYPC 는 넥슨에서 개최하는 청소년 프로그래밍 대회입니다.

매년 여름방학 시즌에 진행되어 비교적 학업에 지장을 덜 받고 출전해 볼 수 있습니다.

학원생 중 이 대회를 준비하는 친구들이 많아 문제풀이를 지속적으로 업데이트할 계획입니다.

자세한 대회 세부 요강 및 기출문제는 NYPC 홈페이지를 참조하기 바랍니다.


NYPC 2023

[본선1214, 영국우편번호]

https://nypc.github.io/2023/final_1

우편번호를 공백으로 나누고 앞, 뒤 패턴을 비교하며 입력이 일치하는지 확인.

def isAlpha(c):
    if ord(c)>=ord('A') and ord(c)<=ord('Z'):
        return True
    return False
    
def isNumber(c):
    if ord(c) >= ord('0') and ord(c)<=ord('9'):
        return True
    return False

def checkPost(s, rule):       
    p = ''
    for c in s:
        if isAlpha(c):
            p+='A'
        elif isNumber(c):
            p+='9'      
            
    if p in rule:
        return True
    
    return False

m = int(input())

front_rule = ('AA9A', 'A9A', 'A9', 'A99', 'AA9', 'AA99')
end_rule = ('9AA',)

for i in range(m):
    a, b = input().split(' ')
    
    f = checkPost(a, front_rule)
    e = checkPost(b, end_rule)
    
    if f and e:
        print('YES')
    else:
        print('NO')


[예선문제, 인류의 적 모기 퇴치]

https://nypc.github.io/2023/round1_p1

N*N 배열마다 십자가, 대각선방향으로 -m 부터 +m 까지 반복하며 얻은 수를 리스트에 저장하고 가장 큰값을 출력.

n, m = map(int, input().split(' '))
lst = [None for _ in range(n)]

for i in range(n):
    temp = list(map(int, input().split(' ')))
    lst[i] = temp
    
mcnt = set()

for i in range(n):
    for j in range(n):        
        # cross
        cnt = 0
        vs = i-m    if i-m>=0   else 0
        ve = i+m+1  if i+m+1<n  else n
        hs = j-m    if j-m>=0   else 0
        he = j+m+1  if j+m+1<n  else n

        for r in range(vs, ve):
            cnt += lst[r][j]
        for c in range(hs, he):
            if c!= j:
                cnt += lst[i][c]            
        mcnt.add(cnt)  
        
        
        # diagonal        
        cnt = 0
        for k in range(-m, m+1):            
            if (i+k>=0 and i+k<n) and (j+k>=0 and j+k<n):
                cnt += lst[i+k][j+k]                            
        
            if (i+k>=0 and i+k<n) and (j-k>=0 and j-k<n):
                if k!=0:
                    cnt += lst[i+k][j-k]            
        mcnt.add(cnt)
        
print(max(mcnt))


[예선문제, 메이플 새로운 직업고르기]

https://nypc.github.io/2023/round1_1

입력받은 직업을 배열에 저장한 후 키워본 직업을 입력받아 리스트에서 제거.

n = int(input())
jobList = []
for _ in range(n):
    job = input()
    jobList.append(job)
    
k = int(input())
for _ in range(k):
    job = input()
    if job in jobList:
        jobList.remove(job)
        
print(len(jobList))
for job in jobList:
    print(job)


[예선문제, 게임 안에서 책을 읽을 수 있다구요?]

https://nypc.github.io/2023/round1_2

입력받은 한줄을 공백을 기준으로 나누고 각 단어들의 시작인덱스와 끝 인덱스를 정리.

단어들의 끝 인덱스가 문서의 폭보다 작은 경우 앞단어의 시작과 끝을 연결시켜 나가며 처리.

def parsingLine(line):
    words_idx = []
    if len(line.split(' '))==1:
        words_idx.append((0, len(line)-1))
    else:
        k=0        
        for i in range(len(line)):
            if line[i]==' ':
                words_idx.append((k, i-1))
                k=i+1
        words_idx.append((k, len(line)-1))
        
    #print(words_idx)
        
    new_idx = []
    s = 0
    e = 0
    k = 0
    for i, v in enumerate(words_idx):        
        if v[1]-v[0]+k+1<=m:
            e = v[1]
            k += v[1]-v[0]+1
        else:
            new_idx.append( (s, e) )
            s = v[0]
            e = v[1]
            k = e-s+1  
        k+=1
    
    new_idx.append( (s, e) )        
    #print(new_idx)

    return new_idx

def noTag(line):
    new_idx = parsingLine(line)    
    
    new_line=''
    for s, e in new_idx:
        word = line[s:e+1].replace(' ', '-')
        k = m-len(word)
        if k==0:
            new_line += word
        else:
            while len(word)<m:
                word += '-'        
            new_line += word
            
        new_line += '\n'
    return new_line[:-1]
    
def centerTag(line):
    new_idx = parsingLine(line)
    
    new_line=''
    for s, e in new_idx:
        word = line[s:e+1].replace(' ', '-')
        k = m-len(word)
        if k==0:
            new_line += word
        elif k==1:
            new_line += word+'-'
        else:
            new_line += '-'*(k//2) + word + '-'*(k//2)
            if k%2==1:
                new_line += '-'
            
        new_line += '\n'
    return new_line[:-1]

def rightTag(line):
    new_idx = parsingLine(line)        
    
    new_line=''
    for s, e in new_idx:
        word = line[s:e+1].replace(' ', '-')
        k = m-len(word)
        if k==0:
            new_line += word
        else:
            while len(word)<m:
                word = '-'+word        
            new_line += word
            
        new_line += '\n'
    return new_line[:-1]

def getAlignText(line, tag=0):    
    #tag 0:none, 1:center, 2:right    
    if line=='<CENTER>':        
        return '', 1
    elif line=='<RIGHT>':
        tag = 2
        return '', 2
    elif line=='</CENTER>' or line=='</RIGHT>':
        return '', 0
    else:
        if tag==0:
            return noTag(line), tag
        elif tag==1:
            return centerTag(line), tag
        else:
            return rightTag(line), tag            

n,m = map(int, input().split(' '))

lines = []
for _ in range(n):
    s = input()
    lines.append(s)    

tag = 0
for line in lines:
    newLine, tag = getAlignText(line, tag)
    if newLine:
        print(newLine)


NYPC 2022

[본선문제, 조약돌 순서]

https://nypc.github.io/2022/final_1

반복의 횟수를 줄여야 하고 Python의 경우 List 자료형으로 인덱스 접근, deque 자료형으로  Rotation을 처리해서 시간제한을 돌파.

import sys
from collections import deque

s = sys.stdin.readline().rstrip()
k, n = map(int, s.split(' '))

if n==0:    
    for i in range(k):        
        sys.stdout.write(f'{i+1} ')
else:    
    x = deque([str(i+1) for i in range(k)])
    z = n//(k-1)%k
   
    for i in range(z):        
        x.rotate(-1)
            
    z = n%(k-1)
    
    x = list(x)
    
    for i in range(z):    
        temp = x[i]
        x[i] = x[i+1]
        x[i+1] = temp         
     
    for c in x:        
        sys.stdout.write(c+' ')       
    
print()


NYPC 2018

[예선문제, 아이템구매]

https://nypc.github.io/2018/2018_online_3.html

부정방정식을 푸는 문제

# y에 대한 방정식
# 1. ax + by = c 
# 2. by = c-ax
# 3. y = (c-ax)/b

p, q, w = map(int, input().split(' '))

i=1

while i*p <= w:
    if (w-(i*p)) % q == 0:
        print(i, (w-(i*p))//q)
        break
    i+=1

 

[예선문제, 승리팀찾기]

https://nypc.github.io/2018/2018_online_4.html

아이템전은 가장 빠른 시간을 찾아 그 팀을 출력하고 스피드전은 정렬 후 등수점수를 팀별로 합산.

def itemWinner(records):
    best = records[0][1]
    idx = 0
    for i in range(8):
        if best > records[i][1]:
            best = records[i][1]
            idx = i    
    return records[idx][0]

def speedWinner(records):
    # sort
    for i in range(8-1):
        for j in range(i+1, 8):
            if records[i][1]>records[j][1]:
                temp = records[i]
                records[i] = records[j]
                records[j] = temp
                
    best = records[0][1]
    red_score = 0
    blue_score = 0
    score = (10, 8, 6, 5, 4, 3, 2, 1)
    
    for i in range(8):
        if records[i][1]-best<10:
            if records[i][0]=='red':
                red_score += score[i]
            else:
                blue_score += score[i]
    
    if red_score>blue_score:
        return 'red'
    elif blue_score>red_score:
        return 'blue'
    else:
        return records[0][0]

#input
n = int(input())

for _ in range(n):
    k = input()
    records = []
    for _ in range(8):
        t, r = input().split(' ')
        minu, sec = map(float, r.split(':'))
        records.append((t, minu*60+sec))
        
    if k=='item':
        print(itemWinner(records))
    else:
        print(speedWinner(records))

 

[예선문제, 줄임말]

https://nypc.github.io/2018/2018_online_5.html

파이썬으로 풀면 쉬운문제. 공백을 기준으로 문장을 잘라내서 UTF-8로 저장.

n = int(input())

try:
    f = open('ouput.txt', mode='w', encoding='utf-8')
except Exception as e:
    print(e)
else:
    for i in range(n):
        lst = input().split(' ')
        for word in lst:
            f.write(word[0])
        if i!=n-1:
            f.write('\n')        
    f.close()

 

[예선문제, 우물왕 김배찌]

https://nypc.github.io/2018/2018_online_6.html

분산을 최소화하는 대표값은 평균.

n = int(input())
xp = 0
yp = 0
for _ in range(n):
    x, y = map(int, input().split(' '))
    xp+=x
    yp+=y
    
print(xp/n, yp/n)

 

[예선문제, 최고의 동접구간을 찾아라]

https://nypc.github.io/2018/2018_online_7.html

예제 입력은 다 해결했는데 BIKO 제출시 틀렸다는데 반례를 모르겠다. 일단은 여기까지..

def hourToMin(hour):
    h, m = map(int, hour.split(':'))
    return h*60 + m

def minToHour(min):
    h = min//60
    m = min%60
    return f'{h:02}:{m:02}'    

n = int(input())

records = []
for i in range(n):
    login, logout = input().split(' ')
    records.append( (hourToMin(login), True) )
    records.append( (hourToMin(logout), False) )
    
# sort
records.sort(key=lambda x: x[0])    

from collections import defaultdict
counts = defaultdict(set)
for num, flag in records:
    counts[num].add(flag)

# 중복되는 항목을 확인
to_remove = {num for num, flags in counts.items() if len(flags) > 1}
# 중복되는 항목을 제거한 새로운 리스트 생성
records = [item for item in records if item[0] not in to_remove]

#print(records)
            
# find segmemt
user = 0
max_user = 0
max_seg = 0
start_time = 0
k = len(records)

for i in range(k):
    isIn = records[i][1]
    if isIn:
        user +=1            
    else:               
        user -=1            
            
    if user>max_user:
        start_time = records[i][0]
        max_user = user
        max_seg = i   
    #print(user)
    

print(max_user)
print(minToHour(start_time), end=' ')

for i in range(max_seg+1, k):
    if records[i][1]==False:
        print(minToHour(records[i][0]))
        break

 

지속적으로 업데이트 예정입니다.

댓글

이 블로그의 인기 게시물

Qt Designer 설치하기

PyQt5 기반 동영상 플레이어앱 만들기