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

 

2110번: 공유기 설치

첫째 줄에 집의 개수 N (2 ≤ N ≤ 200,000)과 공유기의 개수 C (2 ≤ C ≤ N)이 하나 이상의 빈 칸을 사이에 두고 주어진다. 둘째 줄부터 N개의 줄에는 집의 좌표를 나타내는 xi (0 ≤ xi ≤ 1,000,000,000)가

www.acmicpc.net

  • 이진 탐색
더보기

 

  • min, max를 찾고 중간을 돌면서 갱신하는 것이 이진탐색방법 
    • min 값은 배열[1] - 배열[0]을 뺀 값
    • max 값은 배열[-1] - 배열[0]을 뺀 값
  • 최소를 1 최대를 8이라 가정하였을 때 중간값은 8+1//2 가 4가된다.
  • 1, 2와 1, 4의 거리는 갭에 4이하이므로 1,8밖에 설치가 안되며, 8,9 또한 갭이 1이 안되므로 전체 공유기 개수는 2개 되어 다시 Gap를 감소시킨다.이 때 최대 gap은 이전 mid Gap 보다 1을 줄여서 최대 gap으로 설정한다.
  • 현재 미드 gap 값은 다시 계산(min+max //2) 2가 된다.
  • 2를 기준으로 아까처럼 1,2는 x 1,4는 o 4,8은 o 8,9는x로 공유기를 3개까지 설치가 가능하다.
  • 현재 미드 gap 값을 결과 값에 저장하고 가장 큰 경합값을 찾기 위해 최소 gap 값을 증가 시킨다.
  • 서로 만나는 지점의 gap이 되었으므로 미드 gap 또한 3이된다.
  • 1,2x 1,4o 4,8 o, 8,9x로 공유기 3개 조건을 만족하므로 결과값에 현재 gap으로 다시 대입한다. 
n, c = map(int, input().split())
array = []
for _ in range(n):
    array.append(int(input()))
# n,c = 5, 3
# array = [1, 2, 8, 4, 9] #
array = sorted(array)
min, max = 1, array[-1] - array[0]
result = 0
while (min <= max): # 이진 탐색
    mid = (min+max) // 2 # 4, 3.....
    value = array[0]
    count = 1
    
    for i in range(1, len(array)): # 각 데이터를 돌면서 mid 간격 비교 
        if array[i] >= mid+value: # 만약 현재 값이 설정한 mid 값 이상이면
            count +=1 # 공유기 추가
            value = array[i] # 다음 데이터 비교를 위한 value 값 대입
            
    if count >= c: # 공유기 개수가 맞으면
        result = mid # 공유기 결과 저장 
        min = mid + 1 # 더 넓은 폭을 찾기 위해 처음 값 mid +1 로 대입
    else:
        max = mid - 1 # 더 좁은 폭을 찾기 위해 end 값 mid-1로 대입

        
print(result)
  • min, max 값 "min, max = array[1] - array[0], array[-1] - array[0]" 영번 째 인덱스 기준으로 거리를 최대 최소로 구함.
    • min 값을 array[1] - array[0]으로 하니 정답이 계속 틀리다고 나옴. min 값을 1로 고정해주니 정답 처리됨.
  • "while"문은 이진탐색 시 "min", "max" 증 가감하면서 만나기 때문에 그 때까지 반복을 함
    • "mid" 중간 값 설정하고 여기서 중요한건 "value" 값
      • value값이 간격을 계속 체크하기위한 값이 됨
    • "for i in range(1, len(array)): # 각 데이터를 돌면서 mid 간격 비교 "을 통해 각각의 데이터 비교 시작
      • "if array[i] >= mid+value" # 만약 현재 값이 설정한 mid 값 이상이면
                    count +=1 # 공유기 추가
                    value = array[i] # 다음 데이터 비교를 위한 value 값 대입
      • 헷갈린 이유가 계속 "value" 누적이유
        • 1,4,7,10 배열로 계속 들어오는 상황에서 인덱스 비교를 배열[1]부터 시작하며 mid가 3으로 가정을 하면
          • 1,4 비교시 4와 1의 간격이 3이 되었을 때 value 값을 다시 array[i] 로 해줘야 다음 값 4, 7을 현재 간격으로 해서 계속 비교할 수 있음 
    • 비교가 끝난 뒤 만약 공유기 개수가 입력 m 값이면 -> 즉 start 값을 mid+1로 증가 해서 간격을 늘리는게 목적
      • "result = mid # 공유기 결과 저장 "
      • "min = mid + 1 # 더 넓은 폭을 찾기 위해 처음 값 mid +1 로 대입"
    • 개수가 안맞으면 end 값을 mid-1로 해서 현재 mid 간격을 더욱 좁히는게 목적
      •  "max = mid - 1 # 더 좁은 폭을 찾기 위해 end 값 mid-1로 대입"

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

 

1939번: 중량제한

첫째 줄에 N, M(1 ≤ M ≤ 100,000)이 주어진다. 다음 M개의 줄에는 다리에 대한 정보를 나타내는 세 정수 A, B(1 ≤ A, B ≤ N), C(1 ≤ C ≤ 1,000,000,000)가 주어진다. 이는 A번 섬과 B번 섬 사이에 중량제한이

www.acmicpc.net

  • 이진탐색 문제.
더보기
  • 중량 5라고 가정하였을 때 노드 1에서 3까지 이동이 가능하므로 중량을 증가시킴. 
  •  이 때 결과값을 5로 저장함

 

  • 이 때 최소 중량값을 이전 중량 값(5)에서 +1한 6으로 설정하고 현재 중량은 9와 6의 사이값 7로 설정
  • 하지만 현재 중량 값 7은 노드 2에서 3으로 이동할 수 없으므로 중량값을 감소시켜야함.
  • 따라서 감소시키기 위해 최대 중량값을 이전 중량 값"7"에서 -1한 값 "6"을 설정한다.
  • bfs 강의 듣고 다시 풀어봐야할듯

+ Recent posts