ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 백준_곰곰아 선 넘지마_26075(python)
    카테고리 없음 2023. 6. 9. 14:35

    ※ 접근법

     n,m을 더했을 때 문자열의 최대 길이는 십만이고 s와t가 주어진다. 0과 1의 조합이 어떻게 이루어졌을 때 s와 t가 가장 적게 이동해서 값을 만들어낼까?..... 시간제한은 1초 떠오르는 것은 그리디 알고리즘 밖에 없었다. 그렇다면 이것을 어떻게 그리디하게 풀까? 

     처음 떠올렸던 것은 그냥 간단하게 1을 기준으로 더 적게 움직이는 쪽에서 상대방에게 1을 맞추자였다. 이렇게 하니 최소가 아니었다. 여기서!!! 멘붕에 빠져서 헤매다가 결국 친구에게 힌트를 물어봤고 친구는 거리를 좁힌다는 생각을 해보라고 했다.

     

    ★ 풀이

    1. s,t의 1의 좌표를 새로운 s_data, t_data에 저장한다.

    2. 순서대로 하나씩 꺼내 둘의 차이를 구해서 answer에 계속 더한다.

    3. answer을 홀수,짝수 여부를 구분해서 반 씩 나눠가져서 결과값에 더하면 된다.

    문제는 최솟값만 구하면 된다. s와 t중 어느 텍스트가 몇 번을 움직였는지는 궁금하지 않다. 그렇다면 3번만으로 답이 어떻게 입증되는 것일까 그것은 구하는 과정에 의해서 결과가 입증되는 것이다.

    필자는 1의 사이를 좁혀서 값을 구했다. 즉 s와 t의 가장 가까운 1의 거리 차이가 짝수 였다면 둘은 거리 차이의 반 씩 이동했을 것이고 홀수였다면 둘은 거리차이의 반에서 한번 더 움직였을 것이다. 근데 이것은 s가 한번 더 움직였어도 됐고 t가 한번 더 움직였어도 됐다. 여기서 중요한 것은 두 곰곰이는 거리 차이의 반씩 계속 움직였다는 것이다.  

     

    ★ 코드블럭

    n,m = map(int,input().split())
    s = list(input())
    t = list(input())
    snum = tnum = 0
    s_data = []
    t_data = []
    for num in range(len(s)):
        if s[num] == '1':
            s_data.append(num)
        if t[num] == '1':
            t_data.append(num)
    
    answer = 0
    for i in range(len(s_data)):
        answer += abs(s_data[i] - t_data[i])
    re = 0
    if answer % 2 == 0:
        re = (answer // 2) ** 2 * 2
    else:
        re = (answer // 2) ** 2
        re += (answer // 2 + 1) ** 2
    print(re)

    ★ 회고록

     그리디 알고리즘인것을 안 순간 직관적으로 문제를 풀려고 시도했다. 하지만 매번 그리디 알고리즘은 단순하게 풀려고 시도하면서도 단순하게 생각하지 않으려고 한다. 내가 쓰면서도 무슨 말인지 모르겠다. 단순하다의 개념이 추상적이라서 모호한 것 같다. 어느 기준까지가 단순한 것인지 근데 항상 그리디 문제를 풀고나면 단순하다는 생각이 먼저 떠오른다. 그렇다면 이 단순한 것을 왜 떠올리지 못하는 것일까? 너무 쉽게 생각해서인 것 같다. 티어에 대한 존중을 해줘야하는데 그리디인 것을 보면 그냥 단순 직관적으로 풀려고 한다. 이 문제에서도 1을 상대방에게 맞춘다는 것을 떠올리고 최소가 아닌 것을 알았다면 둘의 사이를 좁혀본다는 생각은 떠올릴만 했는데 그렇지 못했다. 그냥 저기서 멘붕에 빠졌다. (이게 아니라고?) 한 번 이렇게 고뇌에 빠지면 혼자 상상의 나래를 펼친다. 보통의 경우 처음 떠올린 방법이 너무 어긋나지만 않았다면 틀을 벗어나지 않는 것 같다. 이 느낌을 잊지말고 계속 기억해보자

Designed by Tistory.