TIL33. algorithm 기초

Jaeyeon·2021년 3월 6일
0
post-thumbnail

1547. 공

문제
세준이는 컵 3개를 탁자 위에 일렬로 엎어놓았다. 컵의 번호는 맨 왼쪽 컵부터 순서대로 1번, 2번 3번이고, 세준이는 이 컵을 이용해서 게임을 하려고 한다.

먼저 1번 컵의 아래에 공을 하나 넣는다. 세준이는 두 컵을 고른 다음, 그 위치를 맞바꾸려고 한다. 예를 들어, 고른 컵이 1번과 2번이라면, 1번 컵이 있던 위치에 2번 컵을 이동시키고, 동시에 2번 컵이 있던 위치에 1번 컵을 이동시켜야 한다. 이때 공은 움직이지 않기 때문에, 공의 위치는 맨 처음 1번 컵이 있던 위치와 같다.

세준이는 컵의 위치를 총 M번 바꿀 것이며, 컵의 위치를 바꾼 방법이 입력으로 주어진다. 위치를 M번 바꾼 이후에 공이 들어있는 컵의 번호를 구하는 프로그램을 작성하시오.

입력
첫째 줄에 컵의 위치를 바꾼 횟수 M이 주어지며, M은 50보다 작거나 같은 자연수이다. 둘째 줄부터 M개의 줄에는 컵의 위치를 바꾼 방법 X와 Y가 주어지며, X번 컵과 Y번 컵의 위치를 서로 바꾸는 것을 의미한다. X와 Y의 값은 3보다 작거나 같고, X와 Y가 같을 수도 있다.

컵을 이동시킨 후에 공이 컵 바깥에 있는 경우는 없다.

출력
첫째 줄에 공이 들어있는 컵의 번호를 출력한다. 공이 사라져서 컵 밑에 없는 경우에는 -1을 출력한다.

예제 입력 1
4
3 1
2 3
3 1
3 2

예제 출력 1
3

n = int(input())
ball = [1,2,3]				# 컵은 3개 고정이므로 리스트 선언
for i in range(n):			# 입력한 n만큼 for문 실행
    a,b = map(int, input().split())	# a,b를 입력받음
    x = ball.index(a)			# 새로운 변수x는 index(a)를 대입
    y = ball.index(b)
    ball[x],ball[y] = ball[y],ball[x]	# ball[x]와 ball[y]를 서로 섞어줌

1598. 꼬리를 무는 숫자 배열

문제
동물원에서 막 탈출한 원숭이 한 마리가 세상구경을 하고 있다. 그 녀석은 원주 부근을 돌아다니다가 코레스코 콘도에서 아주 재밌는 놀이를 발견했다. 그 놀이의 이름은 바로 “꼬리를 무는 숫자 나열”. 이제부터 원숭이가 그토록 좋아하던 그 놀이를 파헤쳐보자.

놀이의 방법은 간단하다. 일단 4줄짜리 표에 왼쪽부터 숫자를 아래로 1부터 순서대로 적어나간다. 다음에 그 예가 잘 나타나있다.
이제 원숭이는 두 개의 자연수를 아무거나 생각한다. 그리고 숫자판에서 두 개의 자연수 사이의 직각거리를 구하면 된다. 여기서 직각거리는 동서방향거리와 남북방향거리의 합을 뜻한다.
예를 들어 저 숫자판에서 11과 33을 생각했다고 하자. 그렇다면 11과 33사이의 직각거리는 8이 된다.(동서방향거리 : 6, 남북방향거리 : 2) 다음 그림에 잘 나타나있다.

하지만 원숭이는 지금 혼란스럽다. 동물원에서 탈출한지 얼마 되지 않아서 계산을 할 수 없는 경지에 이르렀다. 여러분이 불쌍한 원숭이를 좀 도와줘야겠다. 원숭이가 생각한 두 자연수 사이의 직각거리를 구하는 프로그램을 작성하시오.

입력
첫째 줄에 원숭이가 생각한 두 개의 자연수가 주어진다. 각 숫자는 10,000,000 이하이다.

출력
첫째 줄에 원숭이가 생각한 두 개의 자연수 사이의 직각거리를 출력한다.

예제 입력 1
11 33
예제 출력 1
8

import sys
a,b=map(int,sys.stdin.readline().split())
a-=1					# 파이썬은 0 부터 시작하므로 1을 각각 빼준다.
b-=1
print( abs(a//4-b//4)+abs(b%4-a%4))

1703. 생장점

문제
branchorama 나무는 특이한 규칙을 가지고 성장합니다. 어린 branchorama 초목은 하나의 잎을 꼭대기에 가진 가는 묘목이며, 그 잎에는 생장점이 있습니다. 성장하는 계절 동안 나무의 생장점들은 여러 개의 가지로 나뉘게 되며, 성장이 끝나면 각 가지는 생장점을 가진 하나의 잎을 꼭대기에 매달게 됩니다. 놀랍게도 같은 나무의 모든 생장점들은 같은 숫자(splitting factor)의 가지로 나뉘며, 그 숫자는 해가 지남에 따라 변합니다.

아래의 예는 Brown 씨의 과수원에서 한 branchorama 나무가 유목에서부터 3년간 자란 결과를 보여줍니다.

예시에서 예측할 수 있듯이, branchorama 나무는 과밀하게 성장하는 경향이 있습니다. 따라서 Brown 씨는 매 겨울마다 과도하게 성장한 나무들의 가지를 쳐냅니다. 아래는 가지를 쳐낸 branchorama 나무의 예입니다

branchorama 나뭇잎은 굉장히 크고 광합성에 유리하지만, 오직 생장점이 온전히 보존된 가지의 끝에만 달립니다. 따라서 나무가 버티지 못할 정도로 가지를 쳐내는 일은 없어야 합니다.

Brown 씨는 각 나무가 몇 개의 잎을 가졌는지 알고 싶어합니다. 나뭇잎을 일일이 세는 것은 지루하기 때문에, 각 해(level) 성장기의 splitting factor와 그 해 겨울에 쳐낸 가지의 수를 이용해 Brown 씨에게 나뭇잎의 수를 알려주세요.

입력
입력의 각 줄은 하나의 branchorama 나무를 의미합니다.

각 줄은 나무의 나이 a(1 ≤ a ≤ 20)로 시작하며, 그 뒤로 2a 개의 정수가 공백을 두고 주어집니다. 2a 개의 정수는 splitting factor와 가지치기 한 가지의 수가 level 별로 나열된 것입니다.

마지막 줄로 '0'이 주어지며 더 이상의 입력은 없습니다. '0'은 처리하지 않습니다.

출력
각 나무에 대하여 나무에 달려있는 잎의 수를 한 줄씩 출력하세요. 나뭇잎의 수가 signed 32-bit integer를 초과하지 않는다고 가정해도 좋습니다.

예제 입력 1
1 3 0
2 3 0 2 0
3 3 0 2 0 2 0
3 3 0 2 1 2 3
2 4 1 3 4
4 5 0 5 1 5 2 5 101
0
예제 출력 1
3
6
12
7
5
489

while True:
  t = 1					# t는 처음 묘목을 의미
  a = list(map(int, input().split()))	# 입력 받은 값들을 리스트로 선언해줌
  if a[0] != 0:				# a의 첫번째가 0이 아니면
    for i in range(1,a[0]+1):		# 1부터 a의 첫번째 수 까지 for문 실행
        t *= a[2 * i - 1]		# a리스트의 홀수 배열들은 모두 곱해야 하고
        t -= a[2 * i]			# 짝수 배열들은 뺴줘야 한다.
    print(t)				# 가지수를 출력
  else:
      break				# a가 0이면 탈출

1873. 암호제작

문제
원룡이는 한 컴퓨터 보안 회사에서 일을 하고 있다. 그러던 도중, 원룡이는 YESWOA.COM 으로부터 홈페이지 유저들의 비밀키를 만들라는 지시를 받았다. 원룡이는 비밀 키를 다음과 같은 방법으로 만들었다.

개인마다 어떤 특정한 소수 p와 q를 주어 두 소수의 곱 pq를 비밀 키로 두었다. 이렇게 해 주면 두 소수 p,q를 알지 못하는 이상, 비밀 키를 알 수 없다는 장점을 가지고 있다.

하지만 원룡이는 한 가지 사실을 잊고 말았다. 최근 컴퓨터 기술이 발달함에 따라, 소수가 작은 경우에는 컴퓨터로 모든 경우의 수를 돌려보아 비밀 키를 쉽게 알 수 있다는 것이다.

원룡이는 주성조교님께 비밀 키를 제출하려던 바로 직전에 이 사실을 알아냈다. 그래서 두 소수 p, q 중 하나라도 K보다 작은 암호는 좋지 않은 암호로 간주하여 제출하지 않기로 하였다. 이것을 손으로 직접 구해보는 일은 매우 힘들 것이다. 당신은 원룡이를 도와 두 소수의 곱으로 이루어진 암호와 K가 주어져 있을 때, 그 암호가 좋은 암호인지 좋지 않은 암호인지 구하는 프로그램을 작성하여야 한다.

입력
암호 P(4 ≤ P ≤ 10100)와 K (2 ≤ K ≤ 106) 이 주어진다.

출력
만약에 그 암호가 좋은 암호이면 첫째 줄에 GOOD을 출력하고, 만약에 좋지 않은 암호이면 BAD와 소수 r을 공백으로 구분하여 출력하는데 r은 암호를 이루는 두 소수 중 작은 소수를 의미한다.

예제 입력 1
143 10
예제 출력 1
GOOD

예제 입력 2
77 12
예제 출력 2
BAD 7

문제에 나와있는 '소수' 부분에 너무 집중하여 간단한 코드임에도 불구하고 풀지 못했다.

import sys
n, k = map(int, input().split())			
for i in range(2, k):		# 2부터 입력받은 k미만 까지 숫자를 나열 시킨다.
    if n % i == 0:		# 만약 입력받은 n이 i로 나눠 떨어지면
        print(“BAD”, i)		# BAD를 출력시키고 그 i 값을 출력시킨다.(i는 순차적으로 대입되니 어차피 i가 제일 작은 값)
        sys.exit(0)		# for문 탈출
print(“GOOD”)			# 나눠 지는게 없으면 GOOD 출력
profile
생각하는 개발자 되기

0개의 댓글