알고리즘/알고리즘_swea

[Python][SWEA] 1493. 수의 새로운 연산 D3

Jerry_K 2024. 5. 6. 08:32
 

SW Expert Academy

SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!

swexpertacademy.com


🗒️ 파이썬 코드 풀이

i = j = 1
dic = {(i,j) : 1} # 인덱스 위치 -> 좌표값
u_dic = {1 : (i,j)} # 좌표값 -> 인덱스 위치

for n in range(2,50000) :   # 인덱스 위치,좌표값 딕셔너리 형태로 생성
    i -= 1
    j += 1
    if i == 0 :  
        i = j
        j = 1
        
    dic[(i,j)] = n
    u_dic[n] = (i,j)

T = int(input())
for tc in range(1,T+1) : 
    p,q = list(map(int,input().split()))

    x1,y1 = u_dic[q]
    x2,y2 = u_dic[p]
    
    x = x1+x2 
    y = y1+y2 

    ans = dic[(x,y)]

    print(f"#{tc} {ans}")
인덱스위치  좌표값
(1,1) - 1
(2,1) - 2
(1,2) - 3
(3,1) - 4
(2,2) - 5
(1,3) - 6
(4,1) - 7
(3,2) - 8
(2,3) - 9
(1,4) - 10

 

 

1. 먼저 좌표값-인덱스 위치의 딕셔너리를 만들어준다. 

(나는 이 방법을 포기했었는데,  i = 0 일때의 경우를 생각하지 못해 복잡하게 생각했다. )

 

2.  {"좌표값" : "인덱스 위치 "} , {"인덱스 위치" : "좌표값"}  이렇게 2개의 딕셔너리를 만든다. 

 

3. 여기까지하면 , 각각의 key값들을 통해 value를 불러오면 끝이다.

 

*  p,q<=10000인데 딕셔너리 n의 범위를 50000까지 한 이유는 변형되어 나온 x,y 때문이다.

*  왠만한 첫번째는 규칙성이 잘 맞지 않는다.  이럴경우 첫번째는 미리 저장공간에 넣어두고 2부터 시작한다.

 

📑 내 코드 풀이

def tup(x,y) :  # 좌표값 -> 인덱스 위치
    sum = 0 # 누적합
    for i in range(x+y-1) :
        sum += i 
    coor = sum + y  
    return coor
    
def coordinate(p) :  # 인덱스 위치 -> 좌표값
    sum = k = 0   # k는 새롭게 시작되는 첫번째 i 
    while True : 
        k += 1
        sum += k 
        if p <= sum :
            sum -= k
            break
    y = p - sum 
    x = k - y + 1
    return (x,y)

T = int(input())
for tc in range(1,T+1) : 
    p,q = list(map(int,input().split()))

    x1,y1 = coordinate(p)
    x2,y2 = coordinate(q)

    x = x1+x2 
    y = y1+y2 
    
    ans = tup(x,y)
    print(f"#{tc} {ans}")

 

딕셔너리 형태가 너무 복잡 할 것 같다는 생각으로, 사전에 만들어두는게 아니라 필요 할 때마다 값을 구하는 방식으로 했다.  크게 2개의 함수가 있는데 각각 좌표값을 인덱스 위치, 인덱스 위치를 좌표값으로 변경시켜주는 함수이다. 

 

이런 유형은 처음봐서 해당 식을 구하는데 꽤나 시간이 오래 걸렸다.  편한 것은 미리 딕셔너리 형태로 만들어주는 것이지만, 이렇게 수학적 식을 구하여 원하는 값을 도출하는 것도 알아두면 좋을 것 같다.

 

해당 식에 대해 설명이 텍스트를 통해서는 한계가 있는 것 같다.

그래서 간단히 설명을 하자면, 인덱스 위치와 좌표값을 쭉 순서대로 쓰다보면 아래와 같은 규칙을 발견한다.

인덱스위치  좌표값
(1,1) - 1                       1개
------------------------------
(2,1) - 2                       2개
(1,2) - 3
------------------------------
(3,1) - 4                       3개
(2,2) - 5
(1,3) - 6
------------------------------
(4,1) - 7                      4개
(3,2) - 8
(2,3) - 9
(1,4) - 10

 

각 세션의 개수들의 합이 마지막 좌표값이 되고, 세션별 인덱스의 합이 같은 것도 알 수 있다.

이제 관련 식을 도출하면 된다.

📌 문제 코멘트

처음 풀어보는 유형으로 2가지 방법을 기억하자

첫번째 방법 :  딕셔너리 key,value 형태 만들기 

두번째 방법 :  그때 그때 좌표,인덱스 구하기 

 

메모리를 많이 차지 하는 것은 크게 문제가 안되므로, 메모리 <<< 시간 을 신경쓰자.

 


📚 문제


2차원 평면 제 1사분면 위의 격자점 (x,y)에 위 그림과 같이 대각선 순서로 점에 수를 붙인다.

점 (x,y)에 할당된 수는 #(x,y)로 나타낸다.

예를 들어 #(1,1) = 1, #(2,1)=3, #(2,2) = 5, #(4,4) = 25이다.

반대로 수 p가 할당된 점을 &(p)로 나타낸다.

예를 들어 &(1) = (1,1), &(3) = (2,1), &(5) = (2,2), &(25) = (4,4)이다.

두 점에 대해서 덧셈을 정의한다. 점 (x,y)와 점 (z,w)를 더하면 점 (x+z, y+w)가 된다.

즉, (x,y) + (z,w) = (x+z, y+w)로 정의한다.

우리가 해야 할 일은 수와 수에 대한 새로운 연산 ★를 구현하는 것으로, p★q는 #(&(p)+&(q))으로 나타난다.

예를 들어, &(1)=(1,1), &(5) = (2,2)이므로, 1★5 = #(&(1)+&(5)) = #((1,1)+(2,2)) = #(3,3) = 13이 된다.


[입력]

첫 번째 줄에 테스트 케이스의 수 T가 주어진다.

각 테스트 케이스의 첫 번째 줄에는 두 정수 p,q(1 ≤ p, q ≤ 10,000)가 주어진다.


[출력]

각 테스트 케이스마다 ‘#t’(t는 테스트 케이스 번호를 의미하며 1부터 시작한다)를 출력하고, 각 테스트 케이스마다 p★q의 값을 출력한다.