-
백준 2632 피자판매Algorithm/BOJ 2021. 4. 2. 13:14728x90
출처: www.acmicpc.net/problem/2632
분류: 이분탐색
접근방식
이분탐색을 통해 해결해볼 수 있었습니다.
전체적인 풀이 과정은 다음과 같습니다.
1. 각 피자에서 가능한 피자 조각을 모두 구한다. (n == 1000 이므로 n^2 이면 충분합니다.)
2. 한쪽 피자에서 선택했을 경우 또는 하지 않을 경우 다른 쪽 피자의 값이 무엇이 되어야 할지 기대할 수 있기 때문에 이를 이분탐색으로 파악합니다.
가능한 피자 조각을 구할 때 주의해야 할 점은 피자 조각이 원형이라는 점입니다.
주어진 예제처럼 2 2 1 7 2 에서 피자 조각 경우를 구할 때, 원형으로 생각을 해줘야 합니다.
2 2 1 7 2 - 여기서 1부터 시작한다면 가능한 조합은
[1], [1, 7], [1, 7, 2], [1, 7, 2, 2], [1, 7, 2, 2, 2]
이 됩니다! 단 이때 마지막 5가지를 모두 선택하는 경우는 중복되니까 한 번만 포함시켜줘야 합니다.
저는 n-1 까지만 조합을 만들어주고 마지막에 한 번만 5가지를 모두 더한 조각을 추가해주는 방식으로 해결했습니다.
원형은 % 연산을 사용해서 해결해줄 수 있습니다.
for i in 0..<arr.count { var temp = 0 for j in i..<i+arr.count-1 { temp += arr[j % arr.count] table[temp, default: 0] += 1 } }
그리고 저는 중복되는 건 딕셔너리로 개수만 체크해서 처리해줬습니다 :)
이때는 a와 b 에서 원하는 조각 조합을 찾았으면
a 에서 피자 조각 개수 * b에서 피자 조각 개수
로 처리를 해줘야겠죠?
해결방법
일단 a 조합에서 n까지를 돌면서 원하는 피자조각 - an 이 b에서 있나 쭉 확인을 했는데
b 에서만 원하는 피자 조각이 또 있는지 확인해줘야 해서 포문을 나오고 한 번 더 처리를 해줬습니다,.
더 효율적으로 처리할 수도 있을 거 같네요 @_@
let n = Int(readLine()!)! let nm = readLine()!.split(separator: " ").map { Int(String($0))! } var a = [Int]() var b = [Int]() for _ in 0..<nm[0] { a.append(Int(readLine()!)!) } for _ in 0..<nm[1] { b.append(Int(readLine()!)!) } func sum(_ arr: [Int]) -> [Int: Int] { var table = [Int: Int]() for i in 0..<arr.count { var temp = 0 for j in i..<i+arr.count-1 { temp += arr[j % arr.count] table[temp, default: 0] += 1 } } table[arr.reduce(0, +), default: 0] += 1 return table } let aTable = sum(a) let bTable = sum(b) let sumA = [Int](aTable.keys).sorted() let sumB = [Int](bTable.keys).sorted() var resultCase = 0 for an in sumA where an <= n { guard an != n else { resultCase += aTable[an]! break } if let bn = binarySearch(n-an) { resultCase += aTable[an]! * bTable[bn]! } } if let bn = binarySearch(n), let bCase = bTable[bn] { resultCase += bCase } func binarySearch(_ target: Int) -> Int? { var low = 0 var high = sumB.count-1 while low <= high { let mid = (low + high) / 2 if sumB[mid] == target { return sumB[mid] } else if target < sumB[mid] { high = mid-1 } else { low = mid+1 } } return nil } print(resultCase)
배운점
피자조각 개수를 미리 구해놓는 데서 머리가 좀 안 굴러갔는데
찬찬히 적어가면서 이해를 했다.
메모메모..!
'Algorithm > BOJ' 카테고리의 다른 글
백준 17825 주사위 윷놀이 (0) 2021.04.04 백준 17779 게리맨더링 2 (0) 2021.04.04 백준 1981 배열에서 이동 (0) 2021.04.01 백준 3020 개똥벌레 (0) 2021.03.31 백준 1520 내리막 길 (0) 2021.03.30