문제:

동혁이는 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

문제:

JOI시는 남북방향이 H 킬로미터, 동서방향이 W 킬로미터인 직사각형 모양이다. JOI시는 가로와 세로의 길이가 1킬로미터인 H × W 개의 작은 구역들로 나뉘어 있다. 북쪽으로부터 i 번째, 서쪽으로부터 j 번째에 있는 구역을 (i, j) 로 표시한다.

각 구역의 하늘에는 구름이 있을 수도, 없을 수도 있다. 모든 구름은 1분이 지날 때마다 1킬로미터씩 동쪽으로 이동한다. 오늘은 날씨가 정말 좋기 때문에 JOI시의 외부에서 구름이 이동해 오는 경우는 없다.

지금 각 구역의 하늘에 구름이 있는지 없는지를 알고 있다. 기상청에서 일하고 있는 여러분은 각 구역에 대해서 지금부터 몇 분뒤 처음으로 하늘에 구름이 오는지를 예측하는 일을 맡았다.

각 구역에 대해서 지금부터 몇 분뒤 처음으로 하늘에 구름이 오는지를 구하여라.

입력:

입력은 1 + H 행으로 주어진다.

첫 번째 행에는 정수 H, W (1 ≦ H ≦ 100, 1 ≦ W ≦ 100) 가 공백을 사이에 주고 주어진다. 이것은 JOI시가 H × W 개의 작은 구역으로 나뉘어 있다는 것을 의미한다.

이어진 H 개의 행의 i번째 행 (1 ≦ i ≦ H) 에는 W문자의 문자열이 주어진다. W 개의 문자 중 j번째 문자 (1 ≦ j ≦ W) 는, 구역 (i, j) 에 지금 구름이 떠 있는지 아닌지를 나타낸다. 구름이 있는 경우에는 영어 소문자 'c' 가, 구름이 없는 경우에는 문자 '.' 가 주어진다.

출력:

출력은 H 행으로, 각 행에는 공백으로 구분된 W 개의 정수를 출력한다. 출력의 i 번째 행 j 번째 정수 (1 ≦ i ≦ H, 1 ≦ j ≦ W) 는, 지금부터 몇 분후에 처음으로 구역 (i, j) 에 구름이 뜨는지를 표시한다. 단, 처음부터 구역 (i, j) 에 구름이 떠 있었던 경우에는 0을, 몇 분이 지나도 구름이 뜨지 않을 경우에는 -1을 출력한다.

풀이방법:

주어진 조건대로 구현해야 하는 문제다. 이 문제에서는 총 3가지 행동을 수행한다.

1. 지금 하늘에 구름(c)가 있는가?

2. 구름이 몇 분뒤에 지금 하늘에 도착하는가?

3. 구름의 이동

따라서 while 계속해서 반복하고, 1에 의해서 break 조건을 만든다. 그 동안에 2와 3을 반복하며 answer 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
30
31
32
33
34
from collections import deque
 
def check_sky(sky):
    for i in range(H):
        for j in range(W):
            if sky[i][j]=='c':
                return 1
    return 0
 
def update_sky(sky, count):
    for i in range(H):
        for j in range(W):
            if sky[i][j]=='c':
                if answer[i][j]==-1:
                    answer[i][j] = count
 
H, W = map(int,input().split())
answer = [ [-1 for _ in range(W)] for _ in range(H)]
 
sky = []
for _ in range(H):
    sky.append(deque(input()))
    
count = 0
while True:
    if not check_sky(sky):
        break
    update_sky(sky, count)
    for i in range(H):
        sky[i].pop()
        sky[i].appendleft('.')
    count+=1
for ans in answer:
    print(*ans)
cs

문제링크:

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

 

10709번: 기상캐스터

출력은 H 행으로, 각 행에는 공백으로 구분된 W 개의 정수를 출력한다. 출력의 i 번째 행 j 번째 정수 (1 ≦ i ≦ H, 1 ≦ j ≦ W) 는, 지금부터 몇 분후에 처음으로 구역 (i, j) 에 구름이 뜨는지를 표시

www.acmicpc.net

 

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

[BOJ]2852. NBA 농구  (0) 2022.07.28
[BOJ]3474. 교수가 된 현우  (0) 2022.07.26
[BOJ]2870. 수학숙제  (0) 2022.07.19
[BOJ]11758. CCW  (0) 2022.07.14
[BOJ]4659. 비밀번호 발음하기  (0) 2022.07.12

문제:

좋은 패스워드를 만드는것은 어려운 일이다. 대부분의 사용자들은 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

문제:

바퀴와 벨트를 이용하여 실험을 할 수 있는 과학 교구가 있다. 이 교구에는 다양한 종류의 바퀴와 벨트, 그리고 여러 개의 바퀴를 서로 다른 곳에 꽂을 수 있는 교구판이 포함되어 있다.

교구판에는 바퀴를 꽂을 수 있는 축들이 한 줄로 늘어서 있다. 모든 축에 바퀴를 꽂았을 때 바퀴끼리 부딪치지 않도록 축과 축 사이는 충분히 멀리 떨어져 있다. 각 축에는 바퀴가 하나씩 꽂혀있다. 바퀴는 왼쪽부터 순서대로 1번부터 차례대로 번호가 매겨져 있다. 

교구판에서 바로 옆에 있는 두 개의 바퀴는 항상 하나의 벨트로 연결해야 하는데, 이때 벨트를 0자 형태로 연결할 수도 있고 8자 형태로 한번 꼬아서 연결할 수도 있다. 그리고 한쪽 바퀴가 회전하게 되면 벨트로 연결된 다른 바퀴도 회전하게 되는데 이때 두 바퀴의 크기의 차이에 따라 두 바퀴의 회전수가 서로 다를 수 있다. 

다음 예는 3개의 벨트와 4개의 바퀴에 대한 정보가 주어진 경우이다. 이때 벨트 형태는 0자 형태(안꼬인 형태)면 0으로, 8자 형태(꼬인 형태)면 1로 나타낸다.

 

이 경우, 벨트 1은 바퀴 1과 바퀴 2를 0자 형태로 연결하며 바퀴 1이 1번 회전하는 동안 바퀴 2는 2번 회전하게 된다. 즉, 바퀴 1을 시계 방향으로 1회전시키면 바퀴 2는 시계 방향으로 2회전하게 된다. 

벨트 2는 바퀴 2와 바퀴 3을 꼬인 형태로 연결하며 바퀴 2가 1번 회전하는 동안 바퀴 3은 5번 회전하게 되므로, 바퀴 2를 시계 방향으로 1회전시키면 바퀴 3은 반시계 방향으로 5회전하게 된다. 

벨트 3은 바퀴 3과 바퀴 4를 0자 형태로 연결하며 바퀴 3이 2번 회전하는 동안 바퀴 4는 1번 회전하게 되므로, 바퀴 3을 시계 방향으로 2회전시키면 바퀴 4는 시계 방향으로 1회전하게 된다. 

따라서, 처음에 바퀴 1을 시계방향으로 1회전시키면 바퀴 2와 바퀴 3을 거쳐 결국 바퀴 4는 반시계방향으로 5회전하게 된다. 

벨트로 연결된 바퀴들의 회전수의 비와 벨트의 형태가 순서대로 주어졌을 때, 첫 번째 바퀴가 시계 방향으로 분당 1회전을 하는 경우 마지막 바퀴의 회전방향과 분당 회전수를 출력하는 프로그램을 작성하시오.

입력:

첫 줄에는 벨트의 개수를 나타내는 자연수 M(1 ≤ M ≤ 1,000)이 주어진다. 다음 M개의 줄에는 1번 벨트부터 순서대로 벨트로 이어진 두 바퀴의 회전수의 비를 나타내는 두 개의 양의 정수 a, b와 벨트의 형태 0 또는 1이 한 줄에 주어진다. 즉, i번 벨트의 경우, i번 벨트로 이어진 두 바퀴 i와 i+1에 대해 바퀴 i가 a번 회전하는 동안 바퀴 i+1이 b번 회전하고 i번 벨트의 형태가 s(안꼬인 형태는 0, 꼬인 형태는 1)라면 a와 b, 그리고 s가 한 줄에 주어진다. 이때 모든 바퀴의 분당 회전수는 109 이하의 양의 정수로 결정되도록 입력이 주어진다. a, b는 109 이하의 양의 정수이고, a와 b는 서로소이다.

출력:

M+1번 바퀴의 회전 방향(시계방향은 0, 반시계방향은 1)과 분당 회전수를 한줄에 출력한다. 

풀이방법:

 순차적으로 벨트를 이동하며 회전수를 구하면 된다. 회전방향과 같은 경우에는 1이 들어온 경우에만 바뀌므로 나머지 연산을 통해 방향을 바꾼다.

 회전수를 구하는 방법은 b/a를 곱하는 것인데, 이 때, ans*=(b/a)와 같이 하면 에러가 발생하게 된다. 따라서 ans = (ans*b)/a와 같은 방법으로 회전 수를 구하도록 한다.

1
2
3
4
5
6
7
8
9
10
11
12
= int(input())
 
= 0
ans = 1
for _ in range(N):
    a, b, s = map(int, input().split())
    if s==1:
        r = (r+1)%2
    #ans*(b/a)는 에러남
    ans=(ans*b)/a
    
print(r, int(ans))
cs

문제링크:

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

 

10834번: 벨트

첫 줄에는 벨트의 개수를 나타내는 자연수 M(1 ≤ M ≤ 1,000)이 주어진다. 다음 M개의 줄에는 1번 벨트부터 순서대로 벨트로 이어진 두 바퀴의 회전수의 비를 나타내는 두 개의 양의 정수 a, b와 벨

www.acmicpc.net

 

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

[BOJ]2437. 저울  (0) 2022.06.02
[BOJ]8980. 택배  (0) 2022.05.31
[BOJ]8981. 입력숫자  (0) 2022.05.24
[BOJ]2616. 소형기관차  (0) 2022.05.19
[BOJ]2550. 전구  (0) 2022.05.17

문제:

아래 mystery.c는 입력파일 X를 읽어서 그 안에 기록된 N개의 정수를 배열 NUM에 저장한 뒤에 이 N개의 수를 어떤 순서에 따라서 화면에 출력하는 프로그램이다. mystery.c가 X를 입력으로 받아 화면에 출력한 결과를 Y라고 하자.

#include <stdio.h>
int NUM[101] ;
FILE *fin ;
int main(){
    int i, token,N ;
    int count=0, from= 0, value ;
    fin = fopen("X","r");
    fscanf(fin,"%d",&N);
    for(i=0; i<N; i++){
        fscanf(fin,"%d",&token);
        NUM[i]= token;
    } /* end of for */
    printf("%d\n", N ) ;
    value = NUM[ from ] ;
    while( count < N ) {
        while( value == 0 ) { 
            from = (from+1)%N; 
            value = NUM[ from ] ; 
        } /* end of inner while */ 
        printf("%d ", value ) ;
        count++ ;
        NUM[ from ] = 0 ; 
        from = (value +from )% N ; 
        value = NUM[ from ] ; 
    } /* end of outer while */
    return(0);
} /* end of main() */

여러분은 mystery.c에서 생성된 Y를 파일로 받아서 그것의 입력에 해당하는 X를 찾아내는 프로그램을 작성해야 한다. 

입력:

첫 줄에는 정수 N (1 ≤ N ≤ 30)이 주어진다. 그리고 두 번째 줄에는 100이하 양의 정수 N개가 빈칸을 사이에 두고 모두 나열되어 있다. 단 그 정수 중에는 같은 수가 있을 수도 있다.

출력:

첫 줄에는 정수 N이 제시되어 있고, 그 다음 줄에는 N개의 양의 정수가 빈칸을 사이에 두고 기록되어 있어야 한다. 만일 입력을 생성하는 mystery.c의 입력파일 X가 없는 경우에는 음수인 -1 을 첫 줄에 출력하면 된다.

풀이방법:

주어진 코드를 역추적할 수 있도록 구현해야 하는 문제다. X가 없는 경우는 없기 때문에 -1은 고려하지 않아도 된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
= int(input())
= [0]*31
= list(map(int, input().split()))
 
from_ = 0
for value in Y:
    while X[from_] != 0:
        from_ = (from_+1)%N
    X[from_] = value
    from_ = (from_+value)%N
    
print(N)
print(*X[:N])
cs

문제링크:

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

 

8981번: 입력숫자

첫 줄에는 정수 N이 제시되어 있고, 그 다음 줄에는 N개의 양의 정수가 빈칸을 사이에 두고 기록되어 있어야 한다. 만일 입력을 생성하는 mystery.c의 입력파일 X가 없는 경우에는 음수인 -1 을 첫 줄

www.acmicpc.net

 

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

[BOJ]8980. 택배  (0) 2022.05.31
[BOJ]10834. 벨트  (0) 2022.05.26
[BOJ]2616. 소형기관차  (0) 2022.05.19
[BOJ]2550. 전구  (0) 2022.05.17
[BOJ]2116. 주사위 쌓기  (0) 2022.05.12

문제:

천수는 여러 종류의 주사위를 가지고 쌓기 놀이를 하고 있다. 주사위의 모양은 모두 크기가 같은 정육면체이며 각 면에는 1부터 6까지의 숫자가 하나씩 적혀있다. 그러나 보통 주사위처럼 마주 보는 면에 적혀진 숫자의 합이 반드시 7이 되는 것은 아니다.

주사위 쌓기 놀이는 아래에서부터 1번 주사위, 2번 주사위, 3번 주사위, … 의 순서로 쌓는 것이다. 쌓을 때 다음과 같은 규칙을 지켜야 한다: 서로 붙어 있는 두 개의 주사위에서 아래에 있는 주사위의 윗면에 적혀있는 숫자는 위에 있는 주사위의 아랫면에 적혀있는 숫자와 같아야 한다. 다시 말해서, 1번 주사위 윗면의 숫자는 2번 주사위 아랫면의 숫자와 같고, 2번 주사위 윗면의 숫자는 3번 주사위 아랫면의 숫자와 같아야 한다. 단, 1번 주사위는 마음대로 놓을 수 있다.

이렇게 쌓아 놓으면 긴 사각 기둥이 된다. 이 사각 기둥에는 4개의 긴 옆면이 있다. 이 4개의 옆면 중에서 어느 한 면의 숫자의 합이 최대가 되도록 주사위를 쌓고자 한다. 이렇게 하기 위하여 각 주사위를 위 아래를 고정한 채 옆으로 90도, 180도, 또는 270도 돌릴 수 있다. 한 옆면의 숫자의 합의 최댓값을 구하는 프로그램을 작성하시오.

입력:

첫줄에는 주사위의 개수가 입력된다. 그 다음 줄부터는 한 줄에 하나씩 주사위의 종류가 1번 주사위부터 주사위 번호 순서대로 입력된다. 주사위의 종류는 각 면에 적혀진 숫자가 그림1에 있는 주사위의 전개도에서 A, B, C, D, E, F 의 순서로 입력된다. 입력되는 숫자 사이에는 빈 칸이 하나씩 있다. 주사위의 개수는 10,000개 이하이며 종류가 같은 주사위도 있을 수 있다.

그림 1

출력:

첫줄에 한 옆면의 숫자의 합이 가장 큰 값을 출력한다.

풀이방법:

 주사위는 상하로 연결되어 있기 때문에, 이를 위한 새로운 인덱스가 필요하다. 따라서 각 인덱스별로 연관있는 면의 인덱스를 담고 있는 dict을 만들도록 한다.

 그리고 첫 밑면에 따라 모든 경우의 수를 고려할 수 있도록 구현하도록 한다. 1번 주사위에 따라 2번부터 주사위가 결정되기 때문이다. 밑면의 숫자를 고르면 자동으로 윗 숫자가 결정되게 되고, 옆면의 숫자는 회전이 가능하기 때문에 남은 숫자 중에 max 값을 고른다.

 그 뒤로는 첫 주사위의 윗면의 숫자로 다음 주사위의 아래 인덱스가 결정되기 때문에 주사위는 순차적으로 주사위를 올리면서 옆면 중  max 값을 찾으면 된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
= int(input())
dices =[]
dice_index = {0:51:32:43:14:25:0}
for _ in range(N):
    dices.append(list(map(int, input().split())))
 
final_answer= 0 
for i in range(6):
    answers = []
    number = [1,2,3,4,5,6]
    number.remove(dices[0][i])
    up = dices[0][dice_index[i]]
    number.remove(up)
    answers.append(max(number))
    for j in range(1,N):
        number = [1,2,3,4,5,6]
        number.remove(up)
        up = dices[j][dice_index[dices[j].index(up)]]
        number.remove(up)
        answers.append(max(number))
    answers = sum(answers)
    final_answer = max(final_answer, answers)
print(final_answer)
cs

문제링크:

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

 

2116번: 주사위 쌓기

첫줄에는 주사위의 개수가 입력된다. 그 다음 줄부터는 한 줄에 하나씩 주사위의 종류가 1번 주사위부터 주사위 번호 순서대로 입력된다. 주사위의 종류는 각 면에 적혀진 숫자가 그림1에 있는

www.acmicpc.net

 

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

[BOJ]2616. 소형기관차  (0) 2022.05.19
[BOJ]2550. 전구  (0) 2022.05.17
[BOJ]1268. 임시 반장 정하기  (0) 2022.05.10
[BOJ] 2511. 카드놀이  (0) 2022.05.03
[BOJ]2436. 공약수  (0) 2022.04.28

문제:

오민식 선생님은 올해 형택초등학교 6학년 1반 담임을 맡게 되었다. 오민식 선생님은 우선 임시로 반장을 정하고 학생들이 서로 친숙해진 후에 정식으로 선거를 통해 반장을 선출하려고 한다. 그는 자기반 학생 중에서 1학년부터 5학년까지 지내오면서 한번이라도 같은 반이었던 사람이 가장 많은 학생을 임시 반장으로 정하려 한다.

그래서 오민식 선생님은 각 학생들이 1학년부터 5학년까지 몇 반에 속했었는지를 나타내는 표를 만들었다. 예를 들어 학생 수가 5명일 때의 표를 살펴보자.

  1학년 2학년 3학년 4학년 5학년
1번 학생 2 3 1 7 3
2번 학생 4 1 9 6 8
3번 학생 5 5 2 4 4
4번 학생 6 5 2 6 7
5번 학생 8 4 2 2 2

위 경우에 4번 학생을 보면 3번 학생과 2학년 때 같은 반이었고, 3번 학생 및 5번 학생과 3학년 때 같은 반이었으며, 2번 학생과는 4학년 때 같은 반이었음을 알 수 있다. 그러므로 이 학급에서 4번 학생과 한번이라도 같은 반이었던 사람은 2번 학생, 3번 학생과 5번 학생으로 모두 3명이다. 이 예에서 4번 학생이 전체 학생 중에서 같은 반이었던 학생 수가 제일 많으므로 임시 반장이 된다.

각 학생들이 1학년부터 5학년까지 속했던 반이 주어질 때, 임시 반장을 정하는 프로그램을 작성하시오.

입력:

첫째 줄에는 반의 학생 수를 나타내는 정수가 주어진다. 학생 수는 3 이상 1000 이하이다. 둘째 줄부터는 1번 학생부터 차례대로 각 줄마다 1학년부터 5학년까지 몇 반에 속했었는지를 나타내는 5개의 정수가 빈칸 하나를 사이에 두고 주어진다. 주어지는 정수는 모두 1 이상 9 이하의 정수이다.

출력:

첫 줄에 임시 반장으로 정해진 학생의 번호를 출력한다. 단, 임시 반장이 될 수 있는 학생이 여러 명인 경우에는 그 중 가장 작은 번호만 출력한다.

풀이방법:

 학생들간의 정보를 가지고 있는 Nx N 행렬을 만들도록 한다. 그리고 선생님이 만든 각 학생들이 몇 반에 속했었는지를 나타낸 표를 통해 학생들간의 같은 반 유무를 행렬에 담도록 한다. 같은 반이 된 적이 있다면 1로 표기를 하며 넘어가도록 한다. 이 때, 양 방향으로 카운트를 올려주도록 한다. (1번, 3번이 같은 반이 된 적이 있다면 1번, 3번 둘 다 카운트를 올려줘야 한다.)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
= int(input())
 
student = []
for _ in range(n):
    stu = list(map(int,input().split()))
    student.append(stu)
    
answer = [[0 for  _ in range(n)] for _ in range(n)]
for k in range(5):
    for i in range(n):
        for j in range(i+1, n):
            if student[i][k]==student[j][k]:
                answer[i][j] =1
                answer[j][i] =1
 
count = []
for a in answer:
    count.append(a.count(1))
        
print(count.index(max(count))+1)
cs

문제링크:

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

 

1268번: 임시 반장 정하기

첫째 줄에는 반의 학생 수를 나타내는 정수가 주어진다. 학생 수는 3 이상 1000 이하이다. 둘째 줄부터는 1번 학생부터 차례대로 각 줄마다 1학년부터 5학년까지 몇 반에 속했었는지를 나타내는 5

www.acmicpc.net

 

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

[BOJ]2550. 전구  (0) 2022.05.17
[BOJ]2116. 주사위 쌓기  (0) 2022.05.12
[BOJ] 2511. 카드놀이  (0) 2022.05.03
[BOJ]2436. 공약수  (0) 2022.04.28
[BOJ]6976. 절사평균  (0) 2022.04.26

문제:

0부터 9까지의 숫자가 표시된 카드를 가지고 두 사람 A와 B가 게임을 한다. A와 B에게는 각각 0에서 9까지의 숫자가 하나씩 표시된 10장의 카드뭉치가 주어진다. 두 사람은 카드를 임의의 순서로 섞은 후 숫자가 보이지 않게 일렬로 늘어  놓고 게임을 시작한다. 단, 게임 도중 카드의 순서를 바꿀 수는 없다.

A와 B 각각이 늘어놓은 카드를 뒤집어서 표시된 숫자를 확인하는 것을 한 라운드라고 한다. 게임은 첫 번째 놓인 카드부터 시작하여 순서대로 10번의 라운드로 진행된다. 각 라운드에서는 공개된 숫자가 더 큰 사람이 승자가 된다. 승자에게는 승점 3점이 주어지고 패자에게는 승점이 주어지지 않는다. 만약 공개된 두 숫자가 같아서 비기게 되면, A, B 모두에게 승점 1점이 주어진다. 

10번의 라운드가 모두 진행된 후, 총 승점이 큰 사람이 게임의 승자가 된다. 만약, A와 B의 총 승점이 같은 경우에는, 제일 마지막에 이긴 사람을 게임의 승자로 정한다. 그래도 승부가 나지 않는 경우는 모든 라운드에서 비기는 경우뿐이고 이 경우에 두 사람은 비겼다고 한다.

예를 들어, 다음 표에서 3번째 줄은 각 라운드의 승자를 표시하고 있다. 표에서 D는 무승부를 나타낸다. 이 경우에 A의 총 승점은 16점이고, B는 13점이어서, A가 게임의 승자가 된다. 

라운드 1 2 3 4 5 6 7 8 9 10
A 4 5 6 7 0 1 2 3 9 8
B 1 2 3 4 5 6 7 8 9 0
A A A A B B B B D A

아래 표의 경우에는 A와 B의 총 승점은 13점으로 같다. 마지막으로 승부가 난 라운드는 7번째 라운드이고, 이 라운드의 승자인 B가 게임의 승자가 된다. 

라운드 1 2 3 4 5 6 7 8 9 10
A 9 1 7 2 6 3 0 4 8 5
B 6 3 9 2 1 0 7 4 8 5
A B B D A A B D D D

A와 B가 늘어놓은 카드의 숫자가 순서대로 주어질 때, 게임의 승자가 A인지 B인지, 또는 비겼는지 결정하는 프로그램을 작성하시오.

입력:

입력 파일은 두 개의 줄로 이루어진다. 첫 번째 줄에는 A가 늘어놓은 카드의 숫자들이 빈칸을 사이에 두고 순서대로 주어진다. 두 번째 줄에는 B가 늘어놓은 카드의 숫자들이 빈칸을 사이에 두고 순서대로 주어진다. 

출력:

첫 번째 줄에는 게임이 끝난 후, A와 B가 받은 총 승점을 순서대로 빈칸을 사이에 두고 출력한다. 두 번째 줄에는 이긴 사람이 A인지 B인지 결정해서, 이긴 사람을 문자 A 또는 B로 출력한다. 만약 비기는 경우에는 문자 D를 출력한다. 

풀이방법:

 각 라운드를 진행하면서 A의 점수, B의 점수를 더해주도록 한다. 이와 동시에 history라는 배열에 누가 이겼는지 혹은 비겼는지에 대해 기록하도록 한다.

 모든 라운드가 종료한 뒤로, 서로 점수가 다르다면 더 높은 사람을 출력하도록 하고, 점수가 같다면, history를 사용하여 제일 마지막으로 이긴 사람을 찾도록 한다.

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
= list(map(int, input().split()))
= list(map(int, input().split()))
 
a_score = 0
b_score = 0
history = []
for a, b in zip(A, B):
    if a>b:
        a_score+=3
        history.append("A")
    elif a==b:
        a_score+=1
        b_score+=1
        history.append("D")
    else:
        b_score+=3
        history.append("B")
        
print(a_score, b_score)
if a_score > b_score:
    print("A")
elif a_score==b_score:
    idx = len(history)-1
    answer = 'D'
    while idx:
        if history[idx]=='D':
            idx-=1
        else:
            answer= history[idx]
            break
    print(answer)
else:
    print("B")
cs

문제링크:

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

 

2511번: 카드놀이

첫 번째 줄에는 게임이 끝난 후, A와 B가 받은 총 승점을 순서대로 빈칸을 사이에 두고 출력한다. 두 번째 줄에는 이긴 사람이 A인지 B인지 결정해서, 이긴 사람을 문자 A 또는 B로 출력한다. 만약

www.acmicpc.net

 

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

[BOJ]2116. 주사위 쌓기  (0) 2022.05.12
[BOJ]1268. 임시 반장 정하기  (0) 2022.05.10
[BOJ]2436. 공약수  (0) 2022.04.28
[BOJ]6976. 절사평균  (0) 2022.04.26
[BOJ] 2303. 숫자 게임  (0) 2022.04.21

문제:

체조나 다이빙 등의 경기에서 일부 심판이 자기가 좋아하는 선수에게 높은 점수를, 싫어하는 선수에게 낮은 점수를 주는 경우가 종종 있었다. 따라서 심판들이 주는 점수의 평균점수를 선수에게 주게 되면 공정하지 않은 경우가 생길 수 있다. 이를 방지하기 위하여 절사평균이나 보정평균을 사용한다. 예를 들어 심사위원 일곱 명이 다음과 같이 점수를 주었다고 하자.

9.3, 9.5, 9.6, 9.8, 9.1, 5.0, 9.3

전체의 합이 61.6이 되므로 평균은 8.8이 된다. 이 평균점수는 한 심판이 다른 심판에 비하여 아주 낮은 점수인 5.0을 주어서 나온 결과로, 선수는 매우 불공정하다고 느낄 것이다.

위의 점수를 작은데서 큰 순서로 정렬하면 5.0, 9.1, 9.3, 9.3, 9.5, 9.6, 9.8 이 된다.

이때 절사평균(7, 2)는 정렬된 전체 점수 일곱 개 중 양쪽 끝에서 두 개씩을 제외하고 난 9.3, 9.3, 9.5의 평균인 9.37이 된다(소수점이하 셋째 자리에서 반올림). 또 보정평균(7, 2)는 정렬된 전체 점수 일곱 개 중 양쪽 끝에서 각각 두 개를, 남은 점수 중 가장 가까운 것으로 교체한 9.3, 9.3, 9.3, 9.3, 9.5, 9.5, 9.5의 평균으로 9.39가 된다(소수점이하 셋째 자리에서 반올림).

N개의 점수와 양쪽에서 제외하는 개수 K 값이 주어졌을 때 절사평균(N, K)와 보정평균(N, K)를 계산하는 프로그램을 작성하시오.

입력:

첫째 줄에 전체 점수의 개수 N과 제외되는 점수의 개수 K가 빈칸을 사이에 두고 주어진다. N은 3 이상 100,000 이하의 자연수이다. K는 0 이상 (N/2)-1 이하로 주어진다. 그 다음 N줄에는 각 심판의 점수가 한 줄에 하나씩 주어진다. 점수는 0 이상 10 이하의 실수로 소수점이하 첫째 자리까지 주어진다.

출력:

첫째 줄에 절사평균(N, K)를, 둘째 줄에 보정평균(N, K)를 각각 소수점이하 셋째 자리에서 반올림하여 둘째 자리까지 출력한다. 예를 들어 결과값이 9.667인 경우 9.67로, 5인 경우 5.00으로, 5.5인 경우에는 5.50으로 출력한다.

풀이방법:

 조건에 맞게 필요하지 않은 값을 제외하고 평균을 구하면 되는 문제지만, 부동 소수점을 고려해야 한다. 부동 소수점 문제는 컴퓨터가 float을 표현할 때 발생하는 것을 의미한다. 예를 들어 0.3이 입력으로 들어와서 a라는 변수에 저장한다고 해도, a에는 정확히 0.3의 값이 들어가는 것이 아니라 0.3000000000001과 같이 부정확하게 값을 가지게 된다. 따라서 이러한 값들이 누적되어 평균을 구하게 되면 원래 원하던 평균과 달라지게 된다. 따라서 이러한 문제를 해결할 수 있는 여러 가지 방법이 있다.

 일반적으로 float을 지수 부분, 가수 부분으로 나눌 수 있기 때문에 이를 사용하는 방법이 있고, Python에서 이러한 문제점을 해결하기 위해 Decimal이라는 라이브러리를 제공하기도 한다. 하지만 1e-8과 같이 아주 작은 수를 더해주면 해결되는 방법도 있다고 한다. 따라서 평균을 구할 때, 1e-8과 같은 작은 수를 더해 부동소수점 문제를 해결하도록 한다.

1
2
3
4
5
6
import sys
input = sys.stdin.readline
N, K = map(int,input().split())
numbers = sorted([float(input()) for _ in range(N)])
print('{:.2f}'.format(sum(numbers[K:N-K])/(N-2*K)+1e-8))
print('{:.2f}'.format((sum(numbers[K:N-K])+numbers[K]*K+numbers[N-K-1]*K)/+1e-8))
cs

문제링크:

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

 

6986번: 절사평균

첫째 줄에 절사평균(N, K)를, 둘째 줄에 보정평균(N, K)를 각각 소수점이하 셋째 자리에서 반올림하여 둘째 자리까지 출력한다. 예를 들어 결과값이 9.667인 경우 9.67로, 5인 경우 5.00으로, 5.5인 경우

www.acmicpc.net

 

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

[BOJ] 2511. 카드놀이  (0) 2022.05.03
[BOJ]2436. 공약수  (0) 2022.04.28
[BOJ] 2303. 숫자 게임  (0) 2022.04.21
[BOJ]2635. 수 이어가기  (0) 2022.04.19
[BOJ]2596. 비밀편지  (0) 2022.04.14

문제:

병현이는 지은이에게 문자 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

+ Recent posts