문제:

영문 알파벳 대문자로 이루어진 두 단어가 다음의 두 가지 조건을 만족하면 같은 구성을 갖는다고 말한다.

  1. 두 개의 단어가 같은 종류의 문자로 이루어져 있다.
  2. 같은 문자는 같은 개수 만큼 있다.

예를 들어 "DOG"와 "GOD"은 둘 다 'D', 'G', 'O' 세 종류의 문자로 이루어져 있으며 양쪽 모두 'D', 'G', 'O' 가 하나씩 있으므로 이 둘은 같은 구성을 갖는다. 하지만 "GOD"과 "GOOD"의 경우 "GOD"에는 'O'가 하나, "GOOD"에는 'O'가 두 개 있으므로 이 둘은 다른 구성을 갖는다.

두 단어가 같은 구성을 갖는 경우, 또는 한 단어에서 한 문자를 더하거나, 빼거나, 하나의 문자를 다른 문자로 바꾸어 나머지 한 단어와 같은 구성을 갖게 되는 경우에 이들 두 단어를 서로 비슷한 단어라고 한다.

예를 들어 "DOG"와 "GOD"은 같은 구성을 가지므로 이 둘은 비슷한 단어이다. 또한 "GOD"에서 'O'를 하나 추가하면 "GOOD" 과 같은 구성을 갖게 되므로 이 둘 또한 비슷한 단어이다. 하지만 "DOG"에서 하나의 문자를 더하거나, 빼거나, 바꾸어도 "DOLL"과 같은 구성이 되지는 않으므로 "DOG"과 "DOLL"은 비슷한 단어가 아니다.

입력으로 여러 개의 서로 다른 단어가 주어질 때, 첫 번째 단어와 비슷한 단어가 모두 몇 개인지 찾아 출력하는 프로그램을 작성하시오.

입력:

첫째 줄에는 단어의 개수가 주어지고 둘째 줄부터는 한 줄에 하나씩 단어가 주어진다. 모든 단어는 영문 알파벳 대문자로 이루어져 있다. 단어의 개수는 100개 이하이며, 각 단어의 길이는 10 이하이다.

출력:

입력으로 주어진 첫 번째 단어와 비슷한 단어가 몇 개인지 첫째 줄에 출력한다.

풀이방법:

주어진 경우의 수가 많지 않기 때문에 모든 경우의 수에 대해 고려하도록 한다. main으로 선택한 단어는 비교할 단어가 들어올 때마다 복사해서 사용한다.

main 단어와 비교할 단어를 비교하면서 문자가 겹치는 것이 있는지 확인한다. 겹치는 문자가 있다면 remove를 하고 없다면 count를 증가시킨다. 모든 비교를 완료한 뒤에 count가 1 이하, 남은 단어가 1 이하인지 확인하도록 한다. 만약 각 값들이 2보다 크다면 '한 문자를 더하거나, 빼거나, 하나의 문자를 다른 문자로 바꾸어' 조건에 해당하지 않게 된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
= int(input())
 
words = []
for _ in range(N):
    words.append(input())
 
main_word = words[0]
answer = 0
for word in words[1:]:
    target = list(main_word)
    count = 0
    for w in word:
        if w in target:
            target.remove(w)
        else:
            count+=1
 
    if count < 2 and len(target) < 2:
        answer+=1
 
print(answer)
cs

문제링크:

https://www.acmicpc.net/problem/2607

 

2607번: 비슷한 단어

첫째 줄에는 단어의 개수가 주어지고 둘째 줄부터는 한 줄에 하나씩 단어가 주어진다. 모든 단어는 영문 알파벳 대문자로 이루어져 있다. 단어의 개수는 100개 이하이며, 각 단어의 길이는 10 이

www.acmicpc.net

 

'Algorithm > Python' 카테고리의 다른 글

[BOJ] 19637. IF문 좀 대신 써줘  (0) 2023.07.28
[Programmers] Lv 2. 점 찍기  (0) 2023.07.27
[Programmers]Lv 2. 호텔 대실  (0) 2023.07.25
[BOJ] 1515. 수 이어 쓰기  (0) 2023.07.24
[Programmers] Lv 2. 무인도 여행  (0) 2023.07.21

문제:

세준이는 1부터 N까지 모든 수를 차례대로 공백없이 한 줄에 다 썼다. 그리고 나서, 세준이가 저녁을 먹으러 나간 사이에 다솜이는 세준이가 쓴 수에서 마음에 드는 몇 개의 숫자를 지웠다.

세준이는 저녁을 먹으러 갔다 와서, 자기가 쓴 수의 일부가 지워져있는 모습을 보고 충격받았다.

세준이는 수를 방금 전과 똑같이 쓰려고 한다. 하지만, N이 기억이 나지 않는다.

남은 수를 이어 붙인 수가 주어질 때, N의 최솟값을 구하는 프로그램을 작성하시오. 아무것도 지우지 않을 수도 있다.)

입력:

첫째 줄에 지우고 남은 수를 한 줄로 이어 붙인 수가 주어진다. 이 수는 최대 3,000자리다.

출력:

가능한 N 중에 최솟값을 출력한다.

풀이방법:

원래 세준이가 쓴 숫자는 다음과 같을 것이다.

12345678910111213141516....

그래서 앞에서 부터 일치하는 숫자들을 찾고서 더 이상 일치할 숫자를 찾을 수 없을 때까지 반복한다.

 

즉, 234092와 같은 경우에는 1234567891011121314151617181920 중 굵은 숫자의 일부분이 남은 것과 같다. 1부터 하나씩 증가하면서 234092와 비교한다. 2,3,4 에서는 바로 일치되긴 하지만 10부터는 바로 일치되지 않을 것이다. 따라서 자릿수가 늘어난 경우에는 모든 자리에서 일치하는지 여부를 확인하도록 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
= input()
 
= 0
while True:
    i+=1
    num = str(i)
    while len(num) and len(N):
        if num[0]==N[0]:
            N = N[1:]
        num = num[1:]
    if len(N)==0:
        print(i)
        break
cs

문제링크:

https://www.acmicpc.net/problem/1515

 

1515번: 수 이어 쓰기

세준이는 1부터 N까지 모든 수를 차례대로 공백없이 한 줄에 다 썼다. 그리고 나서, 세준이가 저녁을 먹으러 나간 사이에 다솜이는 세준이가 쓴 수에서 마음에 드는 몇 개의 숫자를 지웠다. 세준

www.acmicpc.net

 

'Algorithm > Python' 카테고리의 다른 글

[BOJ] 2607. 비슷한 단어  (0) 2023.07.26
[Programmers]Lv 2. 호텔 대실  (0) 2023.07.25
[Programmers] Lv 2. 무인도 여행  (0) 2023.07.21
[BOJ] 19941. 햄버거 분배  (0) 2023.07.20
[BOJ] 20920. 영단어 암기는 괴로워  (0) 2023.07.19

문제:

화은이는 이번 영어 시험에서 틀린 문제를 바탕으로 영어 단어 암기를 하려고 한다. 그 과정에서 효율적으로 영어 단어를 외우기 위해 영어 단어장을 만들려 하고 있다. 화은이가 만들고자 하는 단어장의 단어 순서는 다음과 같은 우선순위를 차례로 적용하여 만들어진다.

  1. 자주 나오는 단어일수록 앞에 배치한다.
  2. 해당 단어의 길이가 길수록 앞에 배치한다.
  3. 알파벳 사전 순으로 앞에 있는 단어일수록 앞에 배치한다

보다 짧은 길이의 단어의 경우 읽는 것만으로도 외울 수 있기 때문에 길이가 이상인 단어들만 외운다고 한다. 화은이가 괴로운 영단어 암기를 효율적으로 할 수 있도록 단어장을 만들어 주자.

입력:

첫째 줄에는 영어 지문에 나오는 단어의 개수 과 외울 단어의 길이 기준이 되는 이 공백으로 구분되어 주어진다. (1≤ N ≤100,000, 1≤ M ≤10)

둘째 줄부터 번째 줄까지 외울 단어를 입력받는다. 이때의 입력은 알파벳 소문자로만 주어지며 단어의 길이는 을 넘지 않는다.

단어장에 단어가 반드시 1개 이상 존재하는 입력만 주어진다.

출력:

화은이의 단어장에 들어 있는 단어를 단어장의 앞에 위치한 단어부터 한 줄에 한 단어씩 순서대로 출력한다.

풀이방법:

defaultdict을 사용해서 나오는 횟수를 카운팅하며 (key, value) 값을 조건에 맞게 정렬하고 출력하도록 한다.

시간 제한이 걸려 있는 문제이므로 일반 input 대신 sys.stdin.readline을 사용해야 하며, rstrip()으로 개행문자를 제거해 주도록 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import sys
from collections import defaultdict
 
input = sys.stdin.readline
 
N, M = map(int, input().rstrip().split())
count_dict = defaultdict(int)
 
for _ in range(N):
    word = input().rstrip()
    if len(word) >= M:
        count_dict[word]+=1
 
counts = sorted(count_dict.items(), key=lambda x: (-x[1], -len(x[0]), x[0]))
for c in counts:
    print(c[0])
cs

문제링크:

https://www.acmicpc.net/problem/20920

 

20920번: 영단어 암기는 괴로워

첫째 줄에는 영어 지문에 나오는 단어의 개수 $N$과 외울 단어의 길이 기준이 되는 $M$이 공백으로 구분되어 주어진다. ($1 \leq N \leq 100\,000$, $1 \leq M \leq 10$) 둘째 줄부터 $N+1$번째 줄까지 외울 단

www.acmicpc.net

 

문제:

대한민국을 비롯한 대부분의 나라에서는 터널 내에서의 차선 변경을 법률로 금하고 있다. 조금만 관찰력이 있는 학생이라면 터널 내부에서는 차선이 파선이 아닌 실선으로 되어 있다는 것을 알고 있을 것이다. 이는 차선을 변경할 수 없음을 말하는 것이고, 따라서 터널 내부에서의 추월은 불가능하다.

소문난 명콤비 경찰 대근이와 영식이가 추월하는 차량을 잡기 위해 한 터널에 투입되었다. 대근이는 터널의 입구에, 영식이는 터널의 출구에 각각 잠복하고, 대근이는 차가 터널에 들어가는 순서대로, 영식이는 차가 터널에서 나오는 순서대로 각각 차량 번호를 적어 두었다.

N개의 차량이 지나간 후, 대근이와 영식이는 자신들이 적어 둔 차량 번호의 목록을 보고, 터널 내부에서 반드시 추월을 했을 것으로 여겨지는 차들이 몇 대 있다는 것을 알게 되었다. 대근이와 영식이를 도와 이를 구하는 프로그램을 작성해 보자.

입력:

입력은 총 2N+1개의 줄로 이루어져 있다. 첫 줄에는 차의 대수 N(1 ≤ N ≤ 1,000)이 주어진다. 둘째 줄부터 N개의 줄에는 대근이가 적은 차량 번호 목록이 주어지고, N+2째 줄부터 N개의 줄에는 영식이가 적은 차량 번호 목록이 주어진다. 각 차량 번호는 6글자 이상 8글자 이하의 문자열로, 영어 대문자('A'-'Z')와 숫자('0'-'9')로만 이루어져 있다.

같은 차량 번호가 두 번 이상 주어지는 경우는 없다.

출력:

첫째 줄에 터널 내부에서 반드시 추월을 했을 것으로 여겨지는 차가 몇 대인지 출력한다.

풀이방법:

먼저 들어간 차량부터 1이라고 라벨링을 할 때, 추월한 차량의 뒤 차량들 중에는 본인 차의 숫자보다 작은 숫자가 반드시 존재하게 된다. 따라서 이러한 경우를 추월한 차량이라고 생각하고 갯수를 세도록 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
= int(input())
 
in_car = {}
for i in range(1, N+1):
    number = input()
    in_car[number] = i
 
order = []
for j in range(1, N+1):
    out = input()
    order.append(in_car[out])
 
answer = 0
for i in range(N):
    for j in range(i+1, N):
        if order[i] > order[j]:
            answer+=1
            break
 
print(answer)
cs

문제링크:

https://www.acmicpc.net/problem/2002

 

2002번: 추월

입력은 총 2N+1개의 줄로 이루어져 있다. 첫 줄에는 차의 대수 N(1 ≤ N ≤ 1,000)이 주어진다. 둘째 줄부터 N개의 줄에는 대근이가 적은 차량 번호 목록이 주어지고, N+2째 줄부터 N개의 줄에는 영식이

www.acmicpc.net

 

'Algorithm > Python' 카테고리의 다른 글

[Programmers] Lv 2. 롤케이크 자르기  (0) 2023.07.14
[BOJ] 1111. IQ Test  (0) 2023.07.13
[Programmers]Lv 2. 숫자 변환하기  (0) 2023.07.11
[BOJ] 2623. 음악프로그램  (0) 2023.07.10
[BOJ] 1343. 폴리오미노  (0) 2023.07.07

문제:

동혁이는 NBA 농구 경기를 즐겨 본다. 동혁이는 골이 들어갈 때 마다 골이 들어간 시간과 팀을 적는 이상한 취미를 가지고 있다.

농구 경기는 정확히 48분동안 진행된다. 각 팀이 몇 분동안 이기고 있었는지 출력하는 프로그램을 작성하시오.

입력:

첫째 줄에 골이 들어간 횟수 N(1<=N<=100)이 주어진다. 둘째 줄부터 N개의 줄에 득점 정보가 주어진다. 득점 정보는 득점한 팀의 번호와 득점한 시간으로 이루어져 있다. 팀 번호는 1 또는 2이다. 득점한 시간은 MM:SS(분:초) 형식이며, 분과 초가 한자리 일 경우 첫째자리가 0이다. 분은 0보다 크거나 같고, 47보다 작거나 같으며, 초는 0보다 크거나 같고, 59보다 작거나 같다. 득점 시간이 겹치는 경우는 없다.

출력:

첫째 줄에 1번 팀이 이기고 있던 시간, 둘째 줄에 2번 팀이 이기고 있던 시간을 출력한다. 시간은 입력과 같은 형식(MM:SS)으로 출력한다.

풀이방법:

 1번팀과 2번팀과의 점수를 기록하면서 한 팀이 점수를 앞서 나가는 순간에만 시간 차이를 계산하여 각 팀의 시간에 더해주도록 한다. 시간을 더할 때 계산의 편의성을 위해 초 단위로 모두 변환한다.

 중간중간 동점이 되는 경우도 있기 때문에 동점이 되기 전에 시간 차이를 더해준 뒤에 기준이 되는 시간을 갱신하고 각 팀에 점수를 더해주도록 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
= int(input())
timeline = []
for _ in range(N):
    timeline.append(input().split())
timeline = sorted(timeline, key=lambda x: x[1])
timeline.append([-1'48:00'])
one, two = 00
pivot = ''
one_ans, two_ans = 00
for team, time in timeline:
    if one==two:
        pass
    elif one>two:
        min_, sec = map(int,time.split(":"))
        min_p, sec_p = map(int, pivot.split(":"))
        one_ans += (min_*60+sec)-(min_p*60+sec_p)
    else:
        min_, sec = map(int,time.split(":"))
        min_p, sec_p = map(int, pivot.split(":"))
        two_ans += (min_*60+sec)-(min_p*60+sec_p)
    pivot = time
    if int(team)==1:
        one+=1
    elif int(team)==2:
        two+=1
q, r = divmod(one_ans, 60)
print(str(q).zfill(2)+":"+str(r).zfill(2))
q, r = divmod(two_ans, 60)
print(str(q).zfill(2)+":"+str(r).zfill(2))
cs

문제링크:

https://www.acmicpc.net/problem/2852

 

2852번: NBA 농구

첫째 줄에 골이 들어간 횟수 N(1<=N<=100)이 주어진다. 둘째 줄부터 N개의 줄에 득점 정보가 주어진다. 득점 정보는 득점한 팀의 번호와 득점한 시간으로 이루어져 있다. 팀 번호는 1 또는 2이다. 득

www.acmicpc.net

 

'Algorithm > Python' 카테고리의 다른 글

[BOJ]1189. 컴백홈  (0) 2022.08.04
[BOJ]12869.뮤탈리스크  (0) 2022.08.02
[BOJ]3474. 교수가 된 현우  (0) 2022.07.26
[BOJ]10709. 기상캐스터  (0) 2022.07.21
[BOJ]2870. 수학숙제  (0) 2022.07.19

문제:

상근이는 수학시간에 딴 짓을 하다가 선생님께 걸렸다. 선생님은 상근이에게 이번 주말동안 반성하라며 엄청난 숙제를 내주었다.

선생님이 상근이에게 준 종이에는 숫자와 알파벳 소문자로 되어있는 글자가 N줄있다. 상근이는 여기서 숫자를 모두 찾은 뒤, 이 숫자를 비내림차순으로 정리해야한다. 숫자의 앞에 0이 있는 경우에는 정리하면서 생략할 수 있다.

글자를 살펴보다가 숫자가 나오는 경우에는, 가능한 가장 큰 숫자를 찾아야 한다. 즉, 모든 숫자의 앞과 뒤에 문자가 있거나, 줄의 시작 또는 끝이어야 한다.

예를 들어, 01a2b3456cde478에서 숫자를 찾으면 1, 2, 3456, 478이다.

선생님이 준 종이의 내용이 주어졌을 때, 상근이의 숙제를 대신하는 프로그램을 작성하시오.

입력:

첫째 줄에 종이의 줄의 개수 N이 주어진다. (1 ≤ N ≤ 100)

다음 N개의 줄에는 각 줄의 내용이 주어진다. 각 줄은 최대 100글자이고, 항상 알파벳 소문자와 숫자로만 이루어져 있다.

출력:

종이에서 찾은 숫자의 개수를 M이라고 하면, 출력은 M줄로 이루어져야 한다. 각 줄에는 종이에서 찾은 숫자를 하나씩 출력해야 한다. 이때, 비내림차순으로 출력해야 한다. 비내림차순은 내림차순의 반대인 경우인데, 다음 수가 앞의 수보다 크거나 같은 경우를 말한다.

풀이방법:

 python의 isdigit 기능을 사용해서 숫자를 찾도록 한다. 숫자가 연속해서 나오는 경우에는 이어붙이고, 숫자가 아닌 경우에만 배열에 담도록한다. 그리고 맨 끝의 숫자(lo3za4)에서 4도 탐색하기 위해서 for 문이 끝나고 나서 숫자가 남아있다면 추가로 넣어주도록한다.

 이렇게 모든 문자열 탐색이 끝난 뒤에, 배열에 있는 모든 숫자를 int형으로 바꾼 뒤에 정렬을 하도록 한다. (01과 같은 것을 제거하기 위함)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
= int(input())
answer = []
for _ in range(N):
    line = input()
    number = ''
    for l in line:
        if l.isdigit():
            number+=l
        else:
            if len(number):
                answer.append(number)
            number=''
    if len(number):
        answer.append(number)
answer = sorted(list(map(int,answer)))
for ans in answer:
    print(ans)
cs

문제링크:

https://www.acmicpc.net/problem/2870

 

2870번: 수학숙제

종이에서 찾은 숫자의 개수를 M이라고 하면, 출력은 M줄로 이루어져야 한다. 각 줄에는 종이에서 찾은 숫자를 하나씩 출력해야 한다. 이때, 비내림차순으로 출력해야 한다. 비내림차순은 내림차

www.acmicpc.net

 

'Algorithm > Python' 카테고리의 다른 글

[BOJ]3474. 교수가 된 현우  (0) 2022.07.26
[BOJ]10709. 기상캐스터  (0) 2022.07.21
[BOJ]11758. CCW  (0) 2022.07.14
[BOJ]4659. 비밀번호 발음하기  (0) 2022.07.12
[BOJ]2910. 빈도 정렬  (0) 2022.06.30

문제:

좋은 패스워드를 만드는것은 어려운 일이다. 대부분의 사용자들은 buddy처럼 발음하기 좋고 기억하기 쉬운 패스워드를 원하나, 이런 패스워드들은 보안의 문제가 발생한다. 어떤 사이트들은 xvtpzyo 같은 비밀번호를 무작위로 부여해 주기도 하지만, 사용자들은 이를 외우는데 어려움을 느끼고 심지어는 포스트잇에 적어 컴퓨터에 붙여놓는다. 가장 이상적인 해결법은 '발음이 가능한' 패스워드를 만드는 것으로 적당히 외우기 쉬우면서도 안전하게 계정을 지킬 수 있다.

회사 FnordCom은 그런 패스워드 생성기를 만들려고 계획중이다. 당신은 그 회사 품질 관리 부서의 직원으로 생성기를 테스트해보고 생성되는 패스워드의 품질을 평가하여야 한다. 높은 품질을 가진 비밀번호의 조건은 다음과 같다.

  1. 모음(a,e,i,o,u) 하나를 반드시 포함하여야 한다.
  2. 모음이 3개 혹은 자음이 3개 연속으로 오면 안 된다.
  3. 같은 글자가 연속적으로 두번 오면 안되나, ee 와 oo는 허용한다.

이 규칙은 완벽하지 않다;우리에게 친숙하거나 발음이 쉬운 단어 중에서도 품질이 낮게 평가되는 경우가 많이 있다.

입력:

입력은 여러개의 테스트 케이스로 이루어져 있다.

각 테스트 케이스는 한 줄로 이루어져 있으며, 각 줄에 테스트할 패스워드가 주어진다.

마지막 테스트 케이스는 end이며, 패스워드는 한글자 이상 20글자 이하의 문자열이다. 또한 패스워드는 대문자를 포함하지 않는다.

출력:

각 테스트 케이스를 '예제 출력'의 형태에 기반하여 품질을 평가하여라.

풀이방법:

이 문제에는 조건이 3개 있고, 각각 다음과 같이 처리하도록 한다.

 

1. 모음 하나를 반드시 포함하여야 한다.

vowel이라는 리스트를 선언하고, string의 chr 하나씩 보면서 모음인 경우에 vowel_check를 True로 변환해준다. 모든 string 탐색을 마친 뒤에 vowel_check를 확인하도록 한다.

 

2. 모음이 3개 혹은 자음이 3개 연속으로 오면 안 된다.

한 단어를 확인할 때마다. v, nv의 갯수를 업데이트 한다. 각각 vowel, non_vowel을 의미하고, 모음이 나온 경우에는 v++을 하고, nv는 0으로 만들어준다. 자음의 경우에는 반대로 수행한다. 그리고, 둘 중 하나가 3인 경우에는 answer를 False로 바꾼다.

 

3. 같은 글자가 연속적으로 두번 오면 안되나, ee와 oo는 허용한다.

각 chr를 stack에 담으면서 끝 값과 비교하도록 한다. 이 때 만약 같다는 조건문을 통과한 경우에는 answer를 False로 바꾸는데, ee와 oo만 따로 예외상황으로 빼도록 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
vowel = ['a','e','i','o','u']
while True:
    string = input()
    vowel_check=False
    if string=='end':
        break
    stack = []
    v = 0
    nv = 0
    answer= True
    for s in string:
        if s in vowel:
            vowel_check=True
            v+=1
            nv = 0
        else:
            nv+=1
            v= 0
        if nv==3 or v==3:
            answer =False
            break
        if len(stack):
            if stack[-1]==s:
                if s=='e' or s=='o':
                    continue
                answer = False
                break
            stack.append(s)
        else:
            stack.append(s)
            
    if answer and vowel_check:
        print(f"<{string}> is acceptable.")
    else:
        print(f"<{string}> is not acceptable.")
cs

문제링크:

https://www.acmicpc.net/problem/4659

 

4659번: 비밀번호 발음하기

좋은 패스워드를 만드는것은 어려운 일이다. 대부분의 사용자들은 buddy처럼 발음하기 좋고 기억하기 쉬운 패스워드를 원하나, 이런 패스워드들은 보안의 문제가 발생한다. 어떤 사이트들은 xvtp

www.acmicpc.net

 

'Algorithm > Python' 카테고리의 다른 글

[BOJ]2870. 수학숙제  (0) 2022.07.19
[BOJ]11758. CCW  (0) 2022.07.14
[BOJ]2910. 빈도 정렬  (0) 2022.06.30
[BOJ]2828. 사과 담기 게임  (0) 2022.06.28
[BOJ]3986. 좋은 단어  (0) 2022.06.23

문제:

임한수와 임문빈은 서로 사랑하는 사이이다.

임한수는 세상에서 팰린드롬인 문자열을 너무 좋아하기 때문에, 둘의 백일을 기념해서 임문빈은 팰린드롬을 선물해주려고 한다.

임문빈은 임한수의 영어 이름으로 팰린드롬을 만들려고 하는데, 임한수의 영어 이름의 알파벳 순서를 적절히 바꿔서 팰린드롬을 만들려고 한다.

임문빈을 도와 임한수의 영어 이름을 팰린드롬으로 바꾸는 프로그램을 작성하시오.

입력:

첫째 줄에 임한수의 영어 이름이 있다. 알파벳 대문자로만 된 최대 50글자이다.

출력:

첫째 줄에 문제의 정답을 출력한다. 만약 불가능할 때는 "I'm Sorry Hansoo"를 출력한다. 정답이 여러 개일 경우에는 사전순으로 앞서는 것을 출력한다.

풀이방법:

 우선 각 알파벳의 갯수를 count를 한다. 이 때, 홀수 개인 알파벳이 한 개만 있거나 없을 경우에만 팰린드롬을 만들 수 있다. 홀수 개인 알파벳이 하나만 있을때만, 가운데에 배치하여 팰린드롬을 만들 수 있기 때문이다. 따라서 이 조건을 사용해서 우선적으로 필터링해주도록 한다.

 만들 수 있는 경우에는 알파벳을 사전순으로 정렬한 뒤 만들어나가기 시작한다. 각 알파벳의 갯수 M/2개를 문자열에 이어붙이고, 모든 문자열을 순회한 경우에는 다시 역순으로 M/2개를 문자열에 이어 붙이도록 한다. 이 때, 홀수 개인 알파벳이 있었다면, 역순으로 진행하기 전에 먼저 붙이도록 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from collections import Counter
name = input()
= Counter(name)
counts = sorted(c.most_common())
odd_alpha = list(filter(lambda x: x[1]%2==1, counts))
if len(odd_alpha) > 1:
    print("I'm Sorry Hansoo")
else:  
    answer = ""
    for alpha, count in counts:
        answer += alpha*(count//2)
    if len(odd_alpha):
        answer += odd_alpha[0][0]
    counts.reverse()
    for alpha, count in counts:
        answer += alpha*(count//2)
    print(answer)
cs

문제링크:

https://www.acmicpc.net/problem/1213

'Algorithm > Python' 카테고리의 다른 글

[BOJ]3986. 좋은 단어  (0) 2022.06.23
[BOJ]1940. 주몽  (0) 2022.06.21
[BOJ] 9996. 한국이 그리울 땐 서버에 접속하지  (0) 2022.06.14
[BOJ]2437. 저울  (0) 2022.06.02
[BOJ]8980. 택배  (0) 2022.05.31

문제:

병현이는 지은이에게 문자 A, B, C, D, E, F, G, H 로 쓰여진 편지를 날마다 보내는데, 컴퓨터로 보내는 비밀편지로, 한 문자마다 0 또는 1인 숫자 여섯 개를 사용하여 보낸다. 둘 사이의 약속은 다음과 같다.

  • A 000000
  • B 001111
  • C 010011
  • D 011100
  • E 100110
  • F 101001
  • G 110101
  • H 111010

병현이가 어느 날 001111000000011100 을 보내면 지은이는 이것을 BAD로 이해하게 된다. 그런데 둘 사이에 약속이 잘 만들어져 있기 때문에, 통신에 문제가 생겨서 한 문자를 표시하는 여섯 숫자 중 어느 한 숫자만 틀리게 오는 경우, 지은이는 원래 보내려는 문자를 알아 낼 수가 있다.

예를 들어 지은이가 000100을 받았을 때, A와 숫자 한자만 다르고, 다른 문자들과는 각각 숫자 두 자 이상이 다르므로 지은이는 이것이 A라고 알아보게 된다.

다만 111111과 같이 모든 문자의 표현과 숫자 두 자 이상이 다른 경우에는 무슨 문자인지 알 수가 없게 된다. 예를 들어 지은이가 011111000000111111000000111111 을 받았을 때, BA 다음에 알아 볼 수 없는 문자가 나오는데. 이 경우 이런 것이 처음 나오는 문자의 위치인 3을 출력한다.

지은이가 받은 편지를 보고 문자들을 알아내어 출력하거나, 모르는 문자가 있는 경우, 이것이 처음 나오는 위치를 출력하는 프로그램을 작성하시오.

입력:

첫줄에는 보낸 문자의 개수(10개 보다 작다.)가 입력된다. 다음 줄에는 문자의 개수의 여섯 배 만큼의 숫자 입력이 주어진다.

출력:

주어진 입력에서 지은이가 이해한 문자들을 출력하거나, 모르는 문자가 나오는 경우 그런 것이 처음 나오는 위치를 출력한다.

풀이방법:

 단순히 문자열을 한자리씩 비교하며 하는 방식이 아니라 비트연산을 사용한 방법을 사용했다. 우선 알파벳별로 정해진 값들은 0 또는 1인 숫자 여섯 개이기 때문에 이를 이진수라고 생각한다. 따라서 입력받은 문자열을 6자리씩 잘라서 XOR 연산을 통해서 찾도록 한다.

 자른 문자열이 alpha에 있다면 바로 더해주고, 없다면 alpha의 key를 순회하면서 XOR 연산값이 1이 있다면 그 key를 잘못 보낸 것이기 때문에 해당 key의 value 값을 더해주도록 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
alpha = {"000000""A""001111""B""010011""C""011100""D""100110""E","101001":"F""110101""G""111010""H"}
length = int(input())
secret = input()
answer = ""
for i in range(length):
    parse = secret[6*i:6*(i+1)]
    if alpha.get(parse):
        answer += alpha[parse]
    else:
        tmp = ""
        for alp in alpha.keys():
            check = bin((int(alp,2)^int(parse,2)))
            if check.count("1")==1:
                tmp = alpha[alp]
        if tmp:
            answer += tmp
        else:
            print(i+1)
            break
if len(answer)==length:
    print(answer)
cs

문제링크:

https://www.acmicpc.net/problem/2596

 

2596번: 비밀편지

병현이는 지은이에게 문자 A, B, C, D, E, F, G, H 로 쓰여진 편지를 날마다 보내는데, 컴퓨터로 보내는 비밀편지로, 한 문자마다 0 또는 1인 숫자 여섯 개를 사용하여 보낸다. 둘 사이의 약속은 다음과

www.acmicpc.net

 

'Algorithm > Python' 카테고리의 다른 글

[BOJ] 2303. 숫자 게임  (0) 2022.04.21
[BOJ]2635. 수 이어가기  (0) 2022.04.19
[BOJ]2615. 오목  (0) 2022.04.12
[BOJ]2628. 종이자르기  (0) 2022.04.07
[BOJ]9205. 맥주 마시면서 걸어가기  (0) 2022.04.05

문제:

다솜이는 0과 1로만 이루어진 문자열 S를 가지고 있다. 다솜이는 이 문자열 S에 있는 모든 숫자를 전부 같게 만들려고 한다. 다솜이가 할 수 있는 행동은 S에서 연속된 하나 이상의 숫자를 잡고 모두 뒤집는 것이다. 뒤집는 것은 1을 0으로, 0을 1로 바꾸는 것을 의미한다.

예를 들어 S=0001100 일 때,

  1. 전체를 뒤집으면 1110011이 된다.
  2. 4번째 문자부터 5번째 문자까지 뒤집으면 1111111이 되어서 2번 만에 모두 같은 숫자로 만들 수 있다.

하지만, 처음부터 4번째 문자부터 5번째 문자까지 문자를 뒤집으면 한 번에 0000000이 되어서 1번 만에 모두 같은 숫자로 만들 수 있다.

문자열 S가 주어졌을 때, 다솜이가 해야하는 행동의 최소 횟수를 출력하시오.

입력:

첫째 줄에 문자열 S가 주어진다. S의 길이는 100만보다 작다.

출력:

첫째 줄에 다솜이가 해야하는 행동의 최소 횟수를 출력한다.

풀이방법:

 앞에서부터 하나씩 비교해보면서 숫자가 달라지는 횟수를 측정하고 더 작은 변경으로 선택하면 된다. 비교를 할 때, 길이-1의 값까지만 측정했기 때문에 맨 마지막 값의 count도 더해주도록 한다. 만약 하지 않는다면, 10010과 같은 케이스일 때, 오류가 발생할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
from collections import defaultdict
= input()
count = defaultdict(int)
for i in range(1,len(S)):
    if S[i]!=S[i-1]:
        count[S[i-1]]+=1
count[S[-1]]+=1
 
if len(count)!=1:
    print(sorted(count.items(), key = lambda x: x[1])[0][1])
else:
    print(0)
cs

문제링크:

https://www.acmicpc.net/problem/1439

 

1439번: 뒤집기

다솜이는 0과 1로만 이루어진 문자열 S를 가지고 있다. 다솜이는 이 문자열 S에 있는 모든 숫자를 전부 같게 만들려고 한다. 다솜이가 할 수 있는 행동은 S에서 연속된 하나 이상의 숫자를 잡고 모

www.acmicpc.net

 

'Algorithm > Python' 카테고리의 다른 글

[BOJ]2628. 종이자르기  (0) 2022.04.07
[BOJ]9205. 맥주 마시면서 걸어가기  (0) 2022.04.05
[BOJ]2023. 신기한 소수  (0) 2022.03.29
[BOJ]1052. 물병  (0) 2022.03.24
[BOJ]1004. 어린 왕자  (0) 2022.03.22

+ Recent posts