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
지속적으로 업데이트 예정입니다.
댓글
댓글 쓰기