본문 바로가기

알고리즘/BOJ

2632번

2632번 - 피자 판매


이전에 풀었던 문제와 비슷하다. 연속된 부분합의 합의 문제라고 할까?


일단 각 피자의 연속된 합을 모두 구하였다. 그래서 sum1 , sum2 배열에 저장하였다.


연속된 합이기 때문에, N제한이 1000 이므로 충분히 담을 수 있다고 생각했다.


그래서 구해진 두 연속된합의 수열을 하나씩 뽑아서 목표로 하는 값이 되도록 하면 됐다.


또한 각 피자 하나에서도 만들 수 있는 값들이 있기 때문에 , 


sum1,sum2 에 0을 추가해줘서 하나의 피자에서도 값이 나올 수 있다면 정답을 체크 하도록 하였다.


###


나는 풀 때 모든 조각을 구하는 makeAll 함수에서 실수가 발생했다.


피자 전체 한판을 구하는게 중복이 되게도 짜는 등 실수를 많이 했다..


구하고자 하는 값이 크면 더 구할 필요가 없이 바로 다음 조각으로 넘어가는 스킬!


완전탐색을 할 때 중요한 부분인 것 같다. 좋은 문제인 것 같다.


<정답 코드>


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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
 
vector<int> sum1;
vector<int> sum2;
 
void makeAll(vector<int> pizza, int goal, int k)
{
    int left = 0, right = 0, sum = 0;
    bool first = true;
    while (left != pizza.size())
    {
        sum += pizza[right++];
        if (sum <= goal)
        {
            if (k == 1)
            {
                sum1.push_back(sum);
            }
            else
            {
                sum2.push_back(sum);
            }
        }
        else    //값이 크면 그냥 left 증가
        {
            left++;
            right = left;
            sum = 0;
        }
 
        if (right == pizza.size())
        {
            right = 0;
        }
 
        //피자 한판 전체 값 중복 방지
        if (right == left - 1 || (left==0 && right==0))
        {
            left++;
            right = left;
            sum = 0;
        }
    }
}
 
int main()
{
    //freopen("input.txt", "r", stdin);
    int goal, n, m;
    long long ans = 0;
    scanf("%d%d%d"&goal, &n, &m);
    vector<int> pizza1(n);
    vector<int> pizza2(m);
    for (int i = 0; i < n; i++)
    {
        scanf("%d"&pizza1[i]);
    }
    for (int i = 0; i < m; i++)
    {
        scanf("%d"&pizza2[i]);
    }
    sum1.push_back(0);
    sum2.push_back(0);
    makeAll(pizza1, goal, 1);
    makeAll(pizza2, goal, 2);
 
    sort(sum1.begin(), sum1.end());
    sort(sum2.begin(), sum2.end());
 
    int i = 0;
    while (i < sum1.size())
    {
        auto l = lower_bound(sum2.begin(), sum2.end(), goal - sum1[i]);
        auto u = upper_bound(sum2.begin(), sum2.end(), goal - sum1[i]);
 
        ans += u - l;
 
        i++;
    }
 
    printf("%lld\n", ans);
 
 
    return 0;
}
cs


반응형

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

11438번  (0) 2018.01.26
2143번  (0) 2018.01.25
1208번  (0) 2018.01.25
1644번  (0) 2018.01.24
1806번  (0) 2018.01.24