티스토리 뷰
투 포인터를 응용해야 하는 문제이다.
문제에서 배열이 두개가 주어지고, 두개의 배열을 이용하여 만들 수 있는 합 중 T를 만족하는 경우의 수를 찾아야 한다.
완전탐색하는 방법으로는 시간초과를 맞게 되므로 투포인터 알고리즘을 이용해야 한다.
투 포인터 알고리즘을 이용하기 위하여 A와 B배열에 대해 각각의 구간합을 저장하는 사전작업을 했다.
즉, 1,3,2,1 배열이라면 1 4 6 7 3 5 6 2 3 1 라는 별도의 배열을 만든다.
그리고 이렇게 만들어진 두개의 배열을 각각 오름차순으로 정렬 한 후에 하나의 배열은 시작부터, 하나의 배열을 끝부터 시작한다.
이미 이 배열에 구간의 합에 대한 경우의 수가 들어 있으니 이 두개의 배열의 합이 T를 만족하는 개수를 찾으면 된다.
다만 개수를 찾을 때 주의해야할게 있다. 구간합이 중복되는 경우가 반드시 있을 수 있다. 이때 일반적인 방법으로 갯수를 구하게 되면 올바른 값을 구할 수 없다. 그러므로 값을 볼때마다 해당 값이 중복되는 값인지 확인하는 과정이 필요하고 중복되는 경우 중복되는 A배열의 값 갯수 * B배열의 값 갯수를 곱해줘 카운팅 해줘야 한다.
이때 이걸 좀 편하게 하기 위해 나는 map을 이용했다. 또 자료형을 long형으로 하는걸 잊지말자.
/*
21.01.12
BOJ : 두 배열의 합 (https://www.acmicpc.net/problem/2143)
투포인터
*/
#include <bits/stdc++.h>
using namespace std;
int A[1001];
int B[1001];
vector <long long int> subA;
vector <long long int> subB;
map <int, int> countingA;
map <int, int> countingB;
int main() {
cin.tie(NULL);
ios::sync_with_stdio(false);
int T, N,M;
cin >> T;
cin >> N;
for (int i = 0; i < N; i++) {
cin >> A[i];
}
cin >> M;
for (int i = 0; i < M; i++) {
cin >> B[i];
}
for (int i = 0; i < N; i++) {
int sum = 0;
for (int j = i; j < N; j++) {
sum += A[j];
subA.push_back(sum);
countingA[sum]++;
}
}
for (int i = 0; i < M; i++) {
int sum = 0;
for (int j = i; j < M; j++) {
sum += B[j];
subB.push_back(sum);
countingB[sum]++;
}
}
sort(subA.begin(), subA.end());
sort(subB.begin(), subB.end());
int p1 = 0;
int p2 = subB.size() - 1;
long long int cnt = 0;
while (true) {
int sum = subA[p1] + subB[p2];
if (sum > T) {
p2--;
}
else if (sum < T) {
p1++;
}
else { // sum == T
//A에서 갯수세기.
long long int curNumA = subA[p1];
long long int curNumB = subB[p2];
long Acount = countingA[curNumA];
long Bcount = countingB[curNumB];
cnt = cnt + (Acount * Bcount);
p1 += Acount;
p2 -= Bcount;
}
if (p2 < 0 || p1 >= subA.size()) break;
}
cout << cnt;
return 0;
}
'알고리즘 풀이 > 이분탐색' 카테고리의 다른 글
BOJ : 7453 합이 0인 네 정수 (0) | 2021.01.12 |
---|
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- nodeJS
- 구현
- 백트래킹
- 벨만포드
- 알고리즘
- typeORM
- java
- 컴퓨터 통신
- 동적계획법
- nest.js
- BFS
- 컴퓨터 구조
- 자바
- 중앙대학교
- 예외처리
- 그리디
- 그래프
- 스레드
- Computer Architecture
- node.js
- 재귀
- 세그먼트 트리
- boj
- ReactNative
- 백준
- 투포인터
- 자바스크립트
- 시뮬레이션
- dfs
- nestjs
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
글 보관함