Algorithm/백준(BOJ)

[백준 11441] 합 구하기

반응형

[백준 11441] 합 구하기


문제 출처 : https://www.acmicpc.net/problem/11441




문제


N개의 수 A1, A2, ..., AN이 입력으로 주어진다. 총 M개의 구간 i, j가 주어졌을 때, i번째 수부터 j번째 수까지 합을 구하는 프로그램을 작성하시오.




입력


첫째 줄에 수의 개수 N이 주어진다. (1 ≤ N ≤ 100,000) 둘째 줄에는 A1, A2, ..., AN이 주어진다. (-1,000 ≤ Ai ≤ 1,000) 셋째 줄에는 구간의 개수 M이 주어진다. (1 ≤ M ≤ 100,000) 넷째 줄부터 M개의 줄에는 각 구간을 나타내는 i와 j가 주어진다. (1 ≤ i ≤ j ≤ N)




출력


총 M개의 줄에 걸쳐 입력으로 주어진 구간의 합을 출력한다.




예제 입력


1
2
3
4
5
6
7
8
5
10 20 30 40 50
5
1 3
2 4
3 5
1 5
4 4
cs


예제 출력

1
2
3
4
5
60
90
120
150
40
cs


  • 문제 이해하기
 첫 줄에 준 숫자(n)만큼, 다음 줄에 n개의 수를 작성한다. 세번째 줄에 준 숫자(m)만큼, 다음 줄 부터 m개의 원하는 구간의 숫자 합을 구해 출력하는 문제다. 이때 구간은 내가 설정한 숫자만큼의 크기에서 작성해야 하고, n과 m은 1이상 10만 이하이고 두번째 줄에 작성하는 숫자의 크기는 -1000부터 1000 사이의 숫자로 작성해야 한다.  


  • 계획 및 문제 해결
구간의 합을 구하는 가장 좋은 방법은 무엇일까? 위의 예제를 활용해보자.

10 20 30 40 50이 입력되었다면, 아래와 같은 규칙을 가질 것 이다.

2~4구간 합은? (20+30+40) -> 1~4구간 합 - 1구간 합 -> (10+20+30+40) - 10
3~5구간 합은? (30+40+50) -> 1~5구간 합 - 2구간 합 -> (10+20+30+40+50) - (10+20)

이처럼 두 구간을 정했을 때, 뒤에 입력된 구간까지 저장된 총 합에서 앞에 입력된 구간의 바로 앞까지 저장된 합을 빼면 되는 규칙을 발견했다.

그렇다면, 해당구간까지의 합을 저장할 배열도 필요할 것이다.


이제 이러한 규칙을 코드로 작성해보자.

두 번째 줄에 입력되는 수를 배열에 저장하면서, 각 구간 별로 총 합을 더해놓는 sum 배열을 만들었다. 배열을 만들 때 STL 벡터를 사용해보았다. 합계를 저장할 sum배열의 크기를 상수화 시키지 않기 위해서다.

1
2
3
vector<int> v(100001); // 100000개를 저장하는 벡터 생성
vector<int> sum(line + 1); // 합계 저장할 벡터 생성
vector<int> result(100001); // 결과 출력 벡터 생성
cs

개수를 최대 10만까지 넣을 수 있기 때문에, 배열의 크기를 각각 100001로 잡았다.

합계를 저장할 벡터 sum은 1부터 시작할 수 있도록 배열 크기에 +1을 추가시켰다.


우선 첫 줄에 입력할 수를 line이라는 이름의 변수로 선언하고, line만큼 for문을 돌려서 v배열에 값을 넣었다.

그리고 sum배열에는 재귀 함수를 통해 해당 위치까지의 모든 합을 저장시키도록 만들었다.

1
2
3
4
for (int i = 1; i <= line; i++) {
    cin >> v[i];
    sum[i] = v[i] + sum[i - 1];
}
cs

이제 sum배열에는 1부터 해당 배열까지의 합이 저장되어있는 상태다.

앞으로 입력될 구간에서 이 sum배열을 활용하면 된다.



세번째 줄에 입력할 수는 line2라는 이름의 변수를 선언했고, 구간의 시작을 start, 끝을 end로 지정해 결과 값을 result 배열에 저장했다.

1
2
3
4
5
6
7
8
int line2;
cin >> line2;
 
for (int j = 1; j <= line2; j++) {
    int start, end;
    cin >> start >> end;
    result[j] = sum[end- sum[start - 1];
}
cs


이제 result배열만 출력시켜주면 내가 입력한 수만큼의 구간 마다 합계를 나타내 줄 것이다.

1
2
3
for (int z = 1; z <= line2; z++) {
    cout << result[z] << endl;
}
cs



  • 전체 소스 코드
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
#include <iostream>
#include <vector>
 
using namespace std;
 
int main()
{
    int line;
    cin >> line;
 
    vector<int> v(100001); // 100000개를 저장하는 벡터 생성
    vector<int> sum(line + 1); // 합계 저장할 벡터 생성
    vector<int> result(100001); // 결과 출력 벡터 생성
                              
 
    for (int i = 1; i <= line; i++) {
        cin >> v[i];
        sum[i] = v[i] + sum[i - 1];
    }
 
    int line2;
    cin >> line2;
 
    for (int j = 1; j <= line2; j++) {
        int start, end;
        cin >> start >> end;
        result[j] = sum[end- sum[start - 1];
    }
 
    for (int z = 1; z <= line2; z++) {
        cout << result[z] << endl;
    }
 
 
    return 0;
}
cs




반응형

'Algorithm > 백준(BOJ)' 카테고리의 다른 글

[백준 1463] 1로 만들기  (0) 2018.04.12
[백준 1475] 방 번호  (0) 2018.04.10
[백준 2292] 벌집  (0) 2018.04.02
[백준 2438] 별찍기 - 1  (0) 2018.03.31
[백준 2750] 수 정렬하기  (0) 2018.03.29