티스토리 뷰

알고리즘/백준

백준 2632 피자판매 C++

4567은 소수 2022. 10. 10. 02:57

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

 

2632번: 피자판매

첫 번째 줄에는 손님이 구매하고자 하는 피자크기를 나타내는 2,000,000 이하의 자연수가 주어진다. 두 번째 줄에는 A, B 피자의 피자조각의 개수를 나타내 는 정수 m, n 이 차례로 주어진다 (3 ≤ m, n

www.acmicpc.net

map 자료구조를 이용해 풀었습니다. 피자를 n^2으로 start 번호부터 piece개 (정확히는 piece + 1개)를 돌면서 합을 구해줍니다. 그리고 map에 해당 합의 값을 찾아 +1 을 해줍니다. 

최종적으로 맵 중 하나를 골라 iterator를 돌리면서 나머지 피자의 양을 다른 맵에서 찾아줍니다.

 

벡터에 넣고 바이너리 서치를 해도 될 거 같지만 map을 이용해도 풀릴 것 같아 풀어보았습니다.

뭔가 키 값을 계속해서 찾아줘야하기 때문에 시간초과에 간당간당할 것 같았는데 시간 안에는 들어왔습니다. 

(대략적으로 find 할 때 log n 정도 걸리니 (맵이 트리 구조로 이루어짐) n^2 log n 정도 걸림. 따라서 총 복잡도는 대략 2 * n^2 * log n + n * log n => n^2 log n 정도, n이 최대 1000 이지만 find 할 때 항상 log n 나오는 건 아니므로 가능할 것으로 예상되었음)

 

코드는 다음과 같습니다.

 

#include <iostream>
#include <vector>
#include <algorithm>
#include <map>

using namespace std;

int pizza; // 구매하려는 피자 크기 
int m, n; // 조각 m, n개 

map<int,int> A; // 피자 A {크기 합:개수}
map<int,int> B; // 피자 B 

vector<int> vecA; // 피자 A 
vector<int> vecB; // 피자 B 

void init()
{
    cin >> pizza;
    cin >> m >> n;
    
    int num;
    vecA.resize(m);
    vecB.resize(n);
    
    int total = 0;
    for(int i = 0; i < m; i++) {
        cin >> num;
        vecA[i] = num;
        total += num;
    }
    A.insert({total, 1});
    
    total = 0;
    for(int i = 0; i < n; i++) {
        cin >> num;
        vecB[i] = num;
        total += num;
    }
    B.insert({total, 1});
}

void makeMap()
{
    // 모든 조각 합치는 건 처음에 포함 
    int sum, start, piece;
    for(start = 0; start < m; start++) {
        sum = 0;
        for(piece = 0; piece < (m - 1); piece++) {
            sum += vecA[(start + piece) % m];
            A[sum]++; // 키 없으면 A[sum] 초기값 (0) 들어가고 +1
        }
    }
    
    for(start = 0; start < n; start++) {
        sum = 0;
        for(piece = 0; piece < (n - 1); piece++) {
            sum += vecB[(start + piece) % n];
            B[sum]++;
        }
    }
}

int main()
{
    ios_base :: sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    
    init();
    makeMap();
    
    int result = 0;
   
    result += A[pizza];
    result += B[pizza];
    
    // 섞어 만드는 경우 
    auto iterA = A.begin();
    while(iterA != A.end()) {
        int pizzaA = iterA->first;
        int pizzaB = pizza - pizzaA;
        result += A[pizzaA] * B[pizzaB];
        iterA++;
    }
    
    cout << result;
}

'알고리즘 > 백준' 카테고리의 다른 글

백준 2957 이진 탐색 트리 C++  (1) 2022.11.05
백준 1562 계단 수 C++  (0) 2022.10.27
백준 17299 오등큰수 C++  (0) 2022.09.26
백준 16139  (0) 2022.09.25
백준 1103 게임  (0) 2022.09.22
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
TAG
more
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
글 보관함