제목에 써있는 그대로 조금 햇갈렸던 문제이다.

문제를 푸는데 있어서 이 문제야말로 구현이 어려운 것이 아니라 규칙을 찾는 컴퓨팅적 사고 및 논리력이 필요한 문제가 아닌가 싶다.

즉, 문제를 제대로 이해하고 반례까지 없도록 잘 만드는 것이 관건이다.

나는 일부만 제대로 하고, 반례가 생기도록 처음에 만들어서 고생했다.

 

나의 첫 시도(잘못된 코드)는 다음과 같다:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 틀렸다고 나오는 코드
# 1 1 1  ==>  답 101  ==>  출력 102
= int(input())
for i in range(a):  # 몇 개의 출력물을 원하는가
    H, W, N = map(int, input().split())  #입력
    hundred = int(N % H)  #몇 층인지 찾기(백의 자리수 시작)
    decimal = int(N // H) + 1  #몇 호인지 찾기(일의 자리수 시작)
    if (hundred == 0):  # 예를 들어, N층인데 나머지가 0이면, N을 출력한다.
        hundred = H
        if(len(str(decimal)) == 1):  # 일의 자리수 시작해서 십의자리까지 넘어가지 않으면(==> 1~9이면)
            print(f"{hundred}0{decimal}")  # 0을 십의 자리수에 출력한다.
        else:
            print(f"{hundred}{decimal}")  # 십의자리수까지 출력한다.
    else:
        if(len(str(decimal)) == 1):
            print(f"{hundred}0{decimal}")
        else:
            print(f"{hundred}{decimal}")
 
cs

이 코드의 반례는 1 1 1이다. 101이라는 숫자가 나와야 하는데 decimal = int(N//H)+1을 해버렸기 때문에 틀려버렸다.

추가적으로, if~else문을 통해서 print문을 복잡하게 짠 것도 가독성이 떨어지며 속도에도 별로 좋지 않다.


고민을 하고 인터넷을 검색한 결과 다음과 같은 코드가 깔끔하다는 것을 깨닫게 되었다.

1
2
3
4
5
6
7
8
9
10
11
12
= int(input())
for i in range(a):
    H, W, N = map(int, input().split())
    hundred = N % H
    if (hundred == 0):
        hundred = H * 100
        decimal = N // H
    else:
        hundred = (N % H) * 100
        decimal = N // H + 1
    print(hundred + decimal)
 
cs

딱 봐도 깔끔하다. 특히, 내가 위에서 틀린 부분이 확연히 보인다.

decimal이라고 되어있는 부분은 hundred변수가 0일 때와 아닐 때에 따라서 다르게 처리가 되도록 해야한다.

 

이 문제의 경우, 구현의 문제나 파이썬이라는 공부에 있어서의 문제라기보다 논리적 해결의 차원에 문제로 분석할 수 있다 (물론 매우 간단한 문제이지만...).

이런 형태의 문제가 있음을 인지하고, 끊임없이 컴퓨팅적 사고를 기를 필요성을 다시 한 번 느끼게 된다.

 

 

문제출처: https://www.acmicpc.net/problem/10250

 

10250번: ACM 호텔

프로그램은 표준 입력에서 입력 데이터를 받는다. 프로그램의 입력은 T 개의 테스트 데이터로 이루어져 있는데 T 는 입력의 맨 첫 줄에 주어진다. 각 테스트 데이터는 한 행으로서 H, W, N, 세 정수

www.acmicpc.net


직각삼각형은 변의 길이가 3개가 주어졌을 때, 가장 큰 수의 제곱이 다른 두 수의 제곱과 같은 값을 가진다.

이 특징을 사용해서 코딩을 하면 된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
while True:
    tri = list(map(int, input().split()))
    sorted_tri = sorted(tri)
    if sorted_tri[0== 0 or sorted_tri[1== 0 or sorted_tri[2== 0:  # 마지막 줄에 주어지는 입력 케이스이다: 0 0 0
        break
    else:
        pass
 
    if(sorted_tri[0]**2 + sorted_tri[1]**2== sorted_tri[2]**2:
        print("right")
    else:
        print("wrong")
 
cs

 

 

출처: https://www.acmicpc.net/problem/4153

 

4153번: 직각삼각형

입력은 여러개의 테스트케이스로 주어지며 마지막줄에는 0 0 0이 입력된다. 각 테스트케이스는 모두 30,000보다 작은 양의 정수로 주어지며, 각 입력은 변의 길이를 의미한다.

www.acmicpc.net

 


input()을 통해서 풀어도 되긴 하지만, 백준의 채점 프로그램으로 인해서 input()을 시간초과가 계속 나오게 된다.

이럴 때는 sys.stdin.readline()를 사용해야 한다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import sys
 
for _ in range(3):
    N = int(sys.stdin.readline())
    sum = 0
    for i in range(N):
       num = int(sys.stdin.readline())
       sum = sum + num
    
    if sum > 0:
        print("+")
    elif sum < 0:
        print("-")
    else:
        print("0")
cs

 

출처: https://www.acmicpc.net/problem/1247

 

1247번: 부호

총 3개의 테스트 셋이 주어진다. 각 테스트 셋의 첫째 줄에는 N(1≤N≤100,000)이 주어지고, 둘째 줄부터 N개의 줄에 걸쳐 각 정수가 주어진다. 주어지는 정수의 절댓값은 9223372036854775807보다 작거나

www.acmicpc.net

 


문제 자체는 쉬우나, 백준의 채점프로그램상 그냥 while True를 사용하면 런타임 에러(EOFError)가 발생한다.

 

이런 경우, try-except를 사용해서 에러에 대한 예외처리를 해줄 수 있다

 

1
2
3
4
5
while True:
    try:
        print(input())
    except EOFError:
        break
cs

 

출처: https://www.acmicpc.net/problem/11718

 

11718번: 그대로 출력하기

입력이 주어진다. 입력은 최대 100줄로 이루어져 있고, 알파벳 소문자, 대문자, 공백, 숫자로만 이루어져 있다. 각 줄은 100글자를 넘지 않으며, 빈 줄은 주어지지 않는다. 또, 각 줄은 공백으로 시

www.acmicpc.net

 


수학과 관련된 문제이기도 하기 때문에 공식을 조금 찾아보기도 해야하긴 하다.

그래도 제대로 수학적인 공식만 사용한다면 쉬운 문제이다.

1
2
3
4
diagnol, height, width = map(int, input().split())
 
res = diagnol / (height**2 + width**2)**0.5
print(int(height*res), int(width*res))
cs

# 10진수 --> 2 / 8 / 16진수로 변환하기 (1)

파이썬에서는 bin(), oct(), hex()를 통해 이를 쉽게 해결한다.

대신 이 함수들을 통해서 변환을 할 경우,

bin(2진수)는 숫자 앞에 0b가 붙게 된다.

oct(8진수)는 숫자 앞에 0o가 붙게 된다.

hex(16진수)는 숫자 앞에 0x가 붙게 된다.

이런 식으로 나오게 된다.


# 10진수 --> 2 / 8 / 16진수로 변환하기 (2)  --- 앞의 0b, 0o, 0x 지우기

간단한 방법은 print문에서 [2:]로 처리하는 것이다.

[2:]를 통해 0b,0o,0x를 없앴다.

 

또 하나의 방법은 format을 통해서 바꾸는 방법이다.

format을 통해서 바꾼 첫번째 방법이다. 
format을 통해서 바꿀 수 있다.

 

 

{:#b}의 형태로  문자열에 넣은 뒤, format()을 통해서 변환을 하도록 한다. 이 때, [2:]를 통해서 앞의 0b를 출력하지 않도록 처리한다.

 

 

 

 

 

 

 


# n진수 --> 10진수로 변환하기

10진수로 표현하는 방법은 간단하다.

int(string, base)의 형태로 하면 된다.

string은 숫자(값)가 들어가고, base는 string에 입력한 값이 몇진법인지 들어간다.

2, 3, 4, 5, 6, 16진수를 10진수로 바꾸었다.

 


# 참고로, 10진수를 n(2, 8, 16외)진수로 바꾸기 위해서는 직접 변환하는 코드를 작성해서 처리를 해야한다.

매우 간단해 보이지만 틀리고 고민을 꽤 한 문제이다.

이 문제의 핵심은 floating point error이다.

이 문제에서 파이썬을 사용해서 계속 오답이 나온다면 그것은 파이썬의 // 연산자를 사용해야 하기 때문일 것이다.


파이썬에서 // 연산자란?

파이썬에서 나누기 연산 후, 소수점 이하의 수를 버리고 정수 부분의 수만 구한다.

 

print(int(int(N)*int(M)/2))     VS    print(int(int(N)*int(M)//2))

값이 커질수록 서로 결과값이 다르게 나온다.

예를 들어, 999999993 999999993 값을 입력시킨다면 답이 다르게 나올 것이다.

/를 사용하면 : 499999993000000000
//를 사용하면 : 499999993000000024

 

따라서, 위의 문제에 상응하는 답을 가지기 위해서는 //를 사용해야 한다.

1
2
N, M = input().split()
print(int(int(N)*int(M)//2)) 
cs

 

출처: https://www.acmicpc.net/board/view/48568

 

글 읽기 - 최대개수를 잘못 구했나요오오오...

댓글을 작성하려면 로그인해야 합니다.

www.acmicpc.net

 



 

1
2
3
4
5
6
kda = list(map(int, input().split('/')))
if ((kda[0+ kda[2]) < kda[1]) or (kda[1== 0):
    print("hasu")
else:
    print("gosu")
 
cs


간단한 문제이다

대신 문제를 잘 읽자

출력을 보면 3명 사이에 나눠져야 한다고 되어있다. 예제입력 1 때문에 햇갈려서 처음에 틀렸다 허허

암튼, 코드는 다음과 같이 하면 된다.

1
2
3
4
5
6
7
8
9
10
contest_num = int(input())
prize = list(map(int, input().split()))
sum = 0
for i in range(contest_num):
    sum = sum + prize[i]
if sum % 3 != 0:
    print("no")
else:
    print("yes")
 
cs

 

 

출처: https://www.acmicpc.net/problem/20332

 

20332번: Divvying Up

A solid competitive programming team can rack up a lot of prize money. Knowing how strong your team is, you are certain to win a lot of contests, so you had better sit down now and check that everybody will receive the same fair distribution of winnings. Y

www.acmicpc.net

 

+ Recent posts