BOJ/🥈

★Implementation&Simulation Intermediate I - 20 Solved★

metamong 2022. 11. 28.

★ 2941 크로아티아 알파벳 ★

 

s=input()
for c in ['c=','c-','dz=','d-','lj','nj','s=','z=']:
    if c in s:s=s.replace(c,'*')
print(len(s))

 

🌳 replace()


★ 1316 그룹 단어 체커 ★

 

import sys
input=sys.stdin.readline
t=0
for _ in range(int(input())):
    s=input()
    f=0
    for i in range(1,len(s)):
        if s[i]!=s[i-1]:
            if s[i] in s[:i]:
                f+=1
                break
    if f==0:t+=1
print(t)

★ 1213 팰린드롬 만들기 ★

 

import sys
input = sys.stdin.readline

name = input().rstrip()
chs = set(name)
mid = 0
flag = 0

for ch in chs:
    if name.count(ch) % 2 == 1: #홀수 개수인 알파벳이 있다면
        flag += 1
        mid = ch #이를 중앙에 배치
        if flag == 2: #홀수 개수인 알파벳은 최대 1개만 존재하므로 2개 이상이면 불가능
            print("I'm Sorry Hansoo")
            break

if flag < 2: #(1)홀수 개수인 알파벳이 1개 / (2)모든 알파벳이 짝수 개수
    
    if mid != 0: #(1)홀수 개수인 알파벳이 1개 있는 경우
        n = list(name)
        p = n.index(mid)
        del(n[p])
        name = ''.join(n) #1개인 홀수 알파벳만 삭제
    
    name = list(name)
    name.sort() #사전 순 앞서는 걸 먼저 출력 필요
    half_chs = name[::2] #정답의 절반만 떼오기
    
    if flag == 1: #(1)홀수 개수인 알파벳이 1개 있는 경우
        print(''.join(half_chs)+mid+''.join(half_chs[::-1]))
    else: #(2)모든 알파벳이 짝수 개수
        print(''.join(half_chs)+''.join(half_chs[::-1]))

 

🌳 ★ 홀수 개수/짝수 개수 ★

① 홀수 개수인 알파벳 존재한다면

→ 홀수 개수인 알파벳 1개 존재: 정중앙에 배치

→ 홀수 개수인 알파벳 2개 이상 존재: palindrome을 만들 수 없음 - error 발생

 

② 홀수 개수인 알파벳이 존재하지 않는다면

→ palindrome 가능

 

🌳 ★ 사전 순 앞서는 걸 출력 ★

→ list에 넣고 sort()하면 자동적으로 사전순으로 나열. 이 때, index 0부터 2씩 건너뛴 결과끼리 모여 팰린드롬 정답의 왼쪽 절반에 배치, 이를 거꾸로 돌린 뒤 팰린드롬 정답의 오른쪽 절반에 배치


★ 26587 Reverse ★

 

while 1:
    try:
        words=input().split()
        length=len(words)
        reversed_indexes=[]
        reversed_words=[]
        for i in range(length):
            if words[i][0] in 'aeiouAEIOU':
                reversed_indexes.append(i)
        reversed_indexes=reversed_indexes[::-1]
        j=0
        for word in words:
            if word[0] not in 'aeiouAEIOU':
                reversed_words.append(word)
            else:
                reversed_words.append(words[reversed_indexes[j]])
                j+=1

        print(*reversed_words)
    except:break

 

🌳모음으로 시작하는 단어를 찾았다면, 해당 index를 별도의 list에 저장한 뒤, list를 [::-1]로 거꾸로 돌린다. 그 다음 다시 for문을 돌리면서 모음으로 시작하는 단어의 위치라면, 저장한 별도의 index list 첫번째 단어부터 가져온다.


★ 1972 놀라운 문자열 ★

 

import sys
input=sys.stdin.readline

while 1:
    string = input().rstrip()
    if string == '*': break

    ans_dict = dict()

    start_indexes = [i for i in range(len(string)-1)]
    flag = True
    for start_index in start_indexes:
        l=[]
        for i in range(len(string)-1-start_index):
            l.append(string[i]+string[i+start_index+1])
        if len(l) != len(set(l)):
            flag=False
            break
    if flag:
        print(f'{string} is surprising.')
    else:
        print(f'{string} is NOT surprising.')

 

🌳 set()을 사용해 중복 여부 확인 + flag 변수로 확인 (break 장치)


★ 25206 너의 평점은 ★

 

import sys
input=sys.stdin.readline

credit=[]
scores=[]
score_alphabets={'A+':4.5, 'A0':4.0, 'B+':3.5, 'B0':3.0, 'C+':2.5, 'C0':2.0, 'D+':1.5, 'D0':1.0, 'F':0}

for _ in range(20):
    info = input().rstrip()
    hak_jum = info.split()[2]

    if hak_jum != 'P':
        credit.append(float(info.split()[1]))
        scores.append(score_alphabets[hak_jum])

total = 0

for c,s in zip(credit,scores):
    total += c*s

print(total/sum(credit))

 

🌳 split()으로 입력받은 문자열을 부분으로 나누어 학점과 평점에 각각 차례대로 저장 / dictionary 사용해 평점에 맞는 학점 결과를 리스트에 저장 / zip()으로 한 번에 total 구하고 바로 최종 결과 출력!


★ 18221 교수님 저는 취업할래요 ★

 

import sys
input=sys.stdin.readline

N=int(input())
arr=[]
def getdist(x1,y1,x2,y2):
    return ((x2-x1)**2 + (y2-y1)**2)**(1/2)

for row_ind in range(N):
    col=list(map(int,input().split()))
    arr.append(col)
    for col_ind in range(N):
        if col[col_ind] == 5:
            professor=(row_ind,col_ind)
        elif col[col_ind] == 2:
            me=(row_ind,col_ind)


if getdist(professor[0],professor[1],me[0],me[1]) >= 5:
    x1,y1,x2,y2=professor[0],professor[1],me[0],me[1]
    cnt=0
    for x in range(min(x1,x2),max(x1,x2)+1):
        for y in range(min(y1,y2),max(y1,y2)+1):
            if arr[x][y] == 1:
                cnt+=1
    if cnt>=3:
        print(1)
    else:
        print(0)
else:
    print(0)

★ 1244 스위치 켜고 끄기 ★

 

import sys,math
input=sys.stdin.readline
n=int(input())
l=list(map(int,input().split()))

for _ in range(int(input())):
    gender, num = map(int,input().split())
    if gender == 1:
        for i in range(1,n+1):
            if i%num==0:
                l[i-1] = int(not bool(l[i-1]))
    else: #gender = 2
        left,right=num-1,n-num
        limit=min(left,right)
        l[num-1] = int(not bool(l[num-1]))
        for j in range(1,limit+1):
            ll,rr=num-1-j,num-1+j
            if l[ll] == l[rr]:
                l[ll] = int(not bool(l[ll]))
                l[rr] = int(not bool(l[rr]))
            else:
                break

for x in range(math.ceil(n/20)):
    print(*l[20*x:20*x+20])

 

🌳 20개씩 매 줄마다 출력은 math.ceil()로 범위 정하고 20*x부터 index 시작해서 20개씩 출력 구현 / 나머지 구현은 여자일 경우만 좌우대칭 limit 걸어서 진행 / 1을 0으로, 0을 1로 바꾸는 코드는 bool 활용해서 int(not bool) 코드 작성


★ 4402 Soundex ★

 

soundex='01230120022455012623010202'

while 1:
    try:
        word = input().rstrip()
        ans=''
        bf = '!'
        for w in range(len(word)):
            if word[w] != bf:
                k = soundex[ord(word[w])-65]
                if k != '0':
                    if w >= 1:
                        if soundex[ord(word[w])-65] != soundex[ord(word[w-1])-65]:
                            ans+=(soundex[ord(word[w])-65])
                    else:
                        ans+=(soundex[ord(word[w])-65])
            bf = word[w]
        print(ans)

    except:
        break

 

🌳 이전과 soundex의 결과가 같거나, 0이 아닌 경우에만 주의해서 ans 문자열에 붙여서 출력


★ 20200 Crtanje ★

import sys
input=sys.stdin.readline

n=int(input())
chs=list(input().rstrip())
ans=[['.']*n for _ in range(201)]
row = 100

for ch_i in range(n):
    if chs[ch_i] == '+':
        ans[row][ch_i] = '/'
        row-=1
    elif chs[ch_i] == '-':
        row+=1
        ans[row][ch_i] = '\\'
    else: #chs[ch_i] == '='
        ans[row][ch_i] = '_'

for x in ans:
    if '/' in x or '\\' in x or '_' in x:
        print(*x,sep='')

 

🌳 최대 201개 row. 오르락내리락유지 그래프 그대로 구현. 먼저 .으로 모두 구성하고 row에 따라 넣고 바로 구현(기호 \는 앞에 \ 더 붙이기)


★ 15721 번데기 ★

import sys
input=sys.stdin.readline

A=int(input())
T=int(input())
shout=int(input())
noise = '뻔' if shout == 0 else '데'
humans=['']*A
cycle=1
i=0
while 1:
    sentence='뻔데뻔데'+'뻔'*(cycle+1)+'데'*(cycle+1)
    cycle+=1
    for x in sentence:
        if noise == x:
            T-=1
            if T == 0:
                print(i)
                sys.exit()
                
        i+=1
        if i >= A:
            i=0

🌳 cycle마다 후반 뻔과 데의 개수 + 1 / 원이므로 i index가 A 이상일 경우 i = 0 원위치. T번째에서 시작해 noise 만날때마다 -=1


★ 2563 색종이 ★

import sys
input=sys.stdin.readline

arr = [[0]*100 for _ in range(100)]

for _ in range(int(input())):
    x,y=map(int,input().split())
    for row in range(y,y+10):
        for col in range(x,x+10):
            arr[row][col] = 1
cnt=0
for x in range(100):
    for y in range(100):
        if arr[x][y]:
            cnt+=1
print(cnt)

🌳 구현 아이디어: 모든 배열을 0으로 초기화하고, 각 색종이의 영역만 1로 마킹. 전체를 돌려서 1로 마킹된 부분만 카운팅하면 겹침에 상관없이 넓이를 구할 수 있다.


★ 25185 카드 뽑기 ★

import sys
input=sys.stdin.readline

T=int(input())

for _ in range(T):
    cards=list(input().rstrip().split())
    check_duplicates = set(cards)
    cnts=[]
    msp=[[],[],[]]
    got_answer = False
    for pair in check_duplicates:
        if pair[1] == 'm':
            msp[0].append(int(pair[0]))
        elif pair[1] == 's':
            msp[1].append(int(pair[0]))
        else:
            msp[2].append(int(pair[0]))
        cnts.append(cards.count(pair))
    if cnts == [2,2]:
        got_answer = True
        print(':)')
    for cnt in cnts:
        if cnt == 3 or cnt == 4:
            got_answer = True
            print(':)')
            break
    for pair in msp:
        pair.sort()
    if not got_answer:
        for x in msp:
            if len(x)>=3:
                if len(x) == 3:
                    if x[0]+ 1 == x[1] and x[1]+1 == x[2]:
                        got_answer = True
                        print(':)')
                        break
                else: #len(x) == 4
                    if x[0]+1 == x[1]:
                        if x[1]+1 == x[2]:
                            got_answer = True
                            print(':)')
                            break
                    else:
                        if x[1]+1 == x[2]:
                            if x[2]+1 == x[3]:
                                got_answer = True
                                print(':)')
                                break

    if not got_answer:
        print(':(')

★ 8896 가위 바위 보 ★

import sys
input=sys.stdin.readline

for _ in range(int(input())):
    N=int(input())
    robots=[]
    for i in range(N):
        robots.append([i+1]+list(input().rstrip()))
    winners=[i for i in range(1,N+1)]
    num_of_rounds = len(robots[1])-1
    for i in range(num_of_rounds):
        bets=[]
        rsp=[]
        for robot in robots:
            if robot[0] in winners: #let this robot begin in the game
                bets.append((robot[0],robot[i+1]))
                rsp.append(robot[i+1])
        if len(set(rsp)) not in [1,3]: #cut losers
            if 'R' not in set(rsp): #only 'S' & 'P'
                for bet in bets:
                    if bet[1] == 'P': #loser
                        winners.remove(bet[0])
            elif 'S' not in set(rsp): #only 'R' & 'P'
                for bet in bets:
                    if bet[1] == 'R': #loser
                        winners.remove(bet[0])
            else: #only 'R' & 'S'
                for bet in bets:
                    if bet[1] == 'S': #loser
                        winners.remove(bet[0])

    if len(winners)>1:
        print(0)
    else:
        print(winners[0])

🌳 구현 아이디어: 각 로봇의 번호를 달고 다니면서 winners list에 해당 가위/바위/보가 (지는 편) 있다면 remove. 그러나 모두 같은 걸 내거나 모두 다른 걸 내는 경우는 len(set) 활용


★ 4821 페이지 세기 ★

import sys
input=sys.stdin.readline

while 1:
    total = int(input())
    if total == 0:
        break
    pages=[0]*total
    ranges=list(input().rstrip().split(','))
    for x in ranges:
        if '-' not in x:
            if 1<=int(x)<=total:
                pages[int(x)-1] += 1
        else:
            start,end=x.split('-')[0],x.split('-')[1]
            start,end=int(start),int(end)
            if start <= end:
                for y in range(start,end+1):
                    if y>total or y<1:
                        break
                    pages[y-1]+=1
    ans = [True for page in pages if page]
    print(sum(ans))

 

🌳 파싱 잘하고 페이지 범위 넘어갈 경우만 조절해주면 된다. 겹치는 범위와 상관 없이 0으로만 구성된 list pages 만들어서 page 범위에 해당되면 1 증가해, 0보다 큰 page만 카운트해서 출력


★ 30648 트릭 플라워 ★

import sys
input=sys.stdin.readline
a,b=map(int,input().split())
R=int(input())
garden=[[x for x in range(R-i)] for i in range(R)] 
garden[a][b] = '!'
time=0
while 1:
    time+=1
    if (a+1)+(b+1)<R:
        a,b=a+1,b+1
    else:
        a,b=a//2,b//2
        
    if garden[a][b] == '!':
            print(time)
            break
    else:
        garden[a][b] = '!'

 

🌳 문제에서 주어진 대로 그대로 진행


★ 30875 Recovering the Region ★

import sys
input=sys.stdin.readline
N=int(input())

for _ in range(N):
    input()
n=1
for _ in range(N):
    x=[n]*N
    print(*x)
    n+=1

 

🌳 가로줄이나 세로줄을 구역으로 단순히 설정해주는 발상!


★ 13243 Non-decreasing subsegment ★

import sys
input=sys.stdin.readline

n=int(input())
l=list(map(int,input().split()))
ans=l[0]
cur=l[0]
ans_length=1
cur_length=1
for elem_i in range(1,n):
    if l[elem_i] >= l[elem_i-1]:
        cur+=l[elem_i]
        cur_length+=1
        if cur_length > ans_length:
            ans=cur
            ans_length=cur_length
    else:
        cur=l[elem_i]
        cur_length=1
print(ans_length,ans)

 

🌳 연속한 수열 중 가장 긴 길이에서의 수열 내의 숫자 합을 구하는 문제. 가장 긴 길이의 수열이 여러 개 있다면 왼쪽 기준 먼저 등장하는 수열을 고르기. non-decreasing할 경우 ans_length보다 cur_length 길 경우 ans_length update / ans도 cur에서 update. for문 돌려서 누적으로 일정 조건에 맞으면 업데이트 되게 바꾸면 된다.


★ 29791 에르다 노바와 오리진 스킬 ★

import sys
input=sys.stdin.readline
N,M=map(int,input().split())
A,B=sorted(list(map(int,input().split()))),sorted(list(map(int,input().split())))
count_a,count_b=0,0
start_a,start_b=-100,-360

for a in A:
    if (a-start_a)>=100:
        count_a+=1
        start_a=a  

for b in B:
    if (b-start_b)>=360:
        count_b+=1
        start_b=b   

print(count_a,count_b)

 

🌳 재사용 대기 시간보다 면역 시간이 A와 B 모두 짧으므로 면역시간은 상관 x. 재사용 대기 시간을 간격으로 재사용 대기 시간보다 크거나 같다면 카운트. 그리고 해당 시간으로 기준 시간 업데이트. 단순 for문 돌며 카운트 업데이트해서 카운트 최종 출력


★ 10190 Acronyms ★

import sys
input=sys.stdin.readline

N=int(input())

for _ in range(N):
    acronym,n=input().rstrip().split()
    print(acronym)
    for _ in range(int(n)):
        phrase_input=input().rstrip()
        phrase=phrase_input.split()
        is_answer=True
        if len(phrase) == len(acronym):
            for lid in range(len(phrase)):
                if phrase[lid][0] != acronym[lid]:
                    is_answer = False
                    break
        else:
            is_answer = False
        if is_answer:
            print(phrase_input)

댓글