반응형

문제 링크:https://www.acmicpc.net/problem/2075

 

2075번: N번째 큰 수

첫째 줄에 N(1 ≤ N ≤ 1,500)이 주어진다. 다음 N개의 줄에는 각 줄마다 N개의 수가 주어진다. 표에 적힌 수는 -10억보다 크거나 같고, 10억보다 작거나 같은 정수이다.

www.acmicpc.net

<문제 풀이> 우선순위 큐, 정렬

[정렬]


12MB이므로 2550000 크기의 배열 만들고 내림차순 정렬 후 N번째 수 출력

 

<C++ 소스 코드>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
 
int main(void) {
    ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
    int n;
    cin >> n;
    vector<int> v(2550000);
    for (int i = 0; i < n * n; i++)cin >> v[i];
    sort(v.begin(), v.end(), greater<int>());
    cout << v[n-1];
    return 0;
}
cs

 

 

 

[우선순위 큐]

 

행마다 N개를 최소 힙에 push ,pop을 반복하면서 힙에 N개를 유지하면 결국 top에 N 번째로 큰 수가 나온다. 

 

<C++ 소스 코드>

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
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
 
int main(void) {
    ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
 
    int n;
    cin >> n;
    priority_queue<intvector<int>, greater<int> > pq;
    
    for (int i = 0; i < n; i++) {
        int data;
        cin >> data;
        pq.push(data);
    }
 
    for (int i = 1; i < n; i++) {
        for (int j = 0; j < n; j++) {
            int data;
            cin >> data;
            pq.push(data);
        }
        for (int i = 0; i < n; i++)pq.pop();
    }
    cout << pq.top();
    return 0;
}
cs

 

반응형

'알고리즘 문제풀이 > 백준' 카테고리의 다른 글

[백준 2696번] 중앙값 구하기  (0) 2020.03.19
[백준 2014번] 소수의 곱  (0) 2020.03.13
[백준 1715번] 카드 정렬하기  (0) 2020.03.11
[백준 1002번] 터렛  (0) 2020.03.11
[백준 11286번] 절댓값 힙  (0) 2020.03.10
반응형

문제 링크: https://www.acmicpc.net/problem/1715

 

1715번: 카드 정렬하기

정렬된 두 묶음의 숫자 카드가 있다고 하자. 각 묶음의 카드의 수를 A, B라 하면 보통 두 묶음을 합쳐서 하나로 만드는 데에는 A+B 번의 비교를 해야 한다. 이를테면, 20장의 숫자 카드 묶음과 30장의 숫자 카드 묶음을 합치려면 50번의 비교가 필요하다. 매우 많은 숫자 카드 묶음이 책상 위에 놓여 있다. 이들을 두 묶음씩 골라 서로 합쳐나간다면, 고르는 순서에 따라서 비교 횟수가 매우 달라진다. 예를 들어 10장, 20장, 40장의 묶음이 있다면

www.acmicpc.net

<문제 풀이> 우선순위 큐

항상 카드 수가 최소가 되는 카드 묶음끼리 뭉치면 됩니다.

최소 힙을 사용해서 입력받은 데이터를 모두 push 합니다.

 

사이즈가 1이 될 때까지 다음을 반복합니다.

1. 최소 힙에서 두 개를 꺼낸다.

2. 두 개를 더한 결과를 cnt에 추가한다.

3. 두 개를 더한 결과를 최소 힙에 push 한다.

 

<C++ 소스 코드>

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
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
 
int main(void) {
    ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
 
    int n;
    cin >> n;
    priority_queue<intvector<int>, greater<int> > pq;
    while (n--) {
        int num;
        cin >> num;
        pq.push(num);
    }
    int cnt = 0;
    while (pq.size() != 1) {
        int a = pq.top();
        pq.pop();
        int b = pq.top();
        pq.pop();
        cnt += a + b;
        pq.push(a + b);
    }
    cout << cnt;
 
    return 0;
}
cs

 

반응형

'알고리즘 문제풀이 > 백준' 카테고리의 다른 글

[백준 2014번] 소수의 곱  (0) 2020.03.13
[백준 2075번] N번째 큰 수  (0) 2020.03.11
[백준 1002번] 터렛  (0) 2020.03.11
[백준 11286번] 절댓값 힙  (0) 2020.03.10
[백준 1927번] 최소 힙  (0) 2020.03.09
반응형

문제 링크: https://www.acmicpc.net/problem/1002

 

1002번: 터렛

각 테스트 케이스마다 류재명이 있을 수 있는 위치의 수를 출력한다. 만약 류재명이 있을 수 있는 위치의 개수가 무한대일 경우에는 -1을 출력한다.

www.acmicpc.net

<문제 풀이> 기하학

아군의 위치를 A(x1, y1), B(x2, y2), 상대편의 위치를 C(x, y)라고 하고 점과 점 사이의 거리를 계산하면
(x - x1)^2 + (y - y1)^2 = r1^2
(x - x2)^2 + (y - y1)^2 = r2^2

따라서 중심이 A, 반지름이 r1인 원과 중심이 B, 반지름이 r2인 원의 교점의 개수를 찾으면 됩니다.

 

1. 두 원이 일치할 때 (r1 = r2 and A = B)


2. 내접할 때 (선분 AB = r2 - r1)

 

두 원이 내접하면 접하는 점과 두 원의 중심이 일직선상에 위치해 있습니다.


3. 외접할 때 (선분 AB = r1 + r2)

 

두 원이 외접할 때 접하는 점과 두 원의 중심이 일직선상에 위치해 있습니다.



4. 두 원이 떨어져 있을 때 (선분 AB > r2 + r1)


5. 원 안에 원이 있을 때 (선분 AB  < r2 - r1)


6. 원이 두 점에서 만날 때 (선분 AB < r1 + r2)

 

<C++ 소스 코드>

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
#include <iostream>
using namespace std;
 
int main(void) {
    ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
 
    int test_case;
    cin >> test_case;
 
    while (test_case--) {
        int x1, y1, r1, x2, y2, r2;
        cin >> x1 >> y1 >> r1 >> x2 >> y2 >> r2;
        int d1 = (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1);
        int d2 = r1 * r1 + 2*r1 * r2 + r2 * r2;
        int d3 = r1 * r1 - 2 * r1 * r2 + r2 * r2;
 
        if (r1 == r2 && x1 == x2 && y1 == y2) cout << "-1\n"; // 두 원이 일치
        else if (d1 == d3) cout << "1\n"; // 내접
        else if (d1 == d2) cout << "1\n"; // 외접
        else if (d1 > d2) cout << "0\n"; // 두 원이 떨어져있음
        else if (d1 < d3) cout << "0\n"; // 원 안에 다른 원
        else cout << "2\n"; // 두 점에서 만날 때
    }
 
    return 0;
}
cs

 

반응형

'알고리즘 문제풀이 > 백준' 카테고리의 다른 글

[백준 2075번] N번째 큰 수  (0) 2020.03.11
[백준 1715번] 카드 정렬하기  (0) 2020.03.11
[백준 11286번] 절댓값 힙  (0) 2020.03.10
[백준 1927번] 최소 힙  (0) 2020.03.09
[백준 11279번] 최대 힙  (0) 2020.03.09
반응형

문제 링크: https://www.acmicpc.net/problem/11286

 

11286번: 절댓값 힙

첫째 줄에 연산의 개수 N(1≤N≤100,000)이 주어진다. 다음 N개의 줄에는 연산에 대한 정보를 나타내는 정수 x가 주어진다. 만약 x가 0이 아니라면 배열에 x라는 값을 넣는(추가하는) 연산이고, x가 0이라면 배열에서 절댓값이 가장 작은 값을 출력하고 그 값을 배열에서 제거하는 경우이다. 입력되는 정수는 -231보다 크고, 231보다 작다.

www.acmicpc.net

<문제 풀이> 우선순위 큐

pair로 최소 힙을 만들면 되는데 frist는 x 절댓값을 저장하고 second는 x의 원본을 저장하면 된다.

(절댓값의 최소니깐 first 기준으로 최소 힙을 만들면 됨)

 

<C++ 소스 코드>

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
#include <iostream>
#include <cmath>
#include <queue>
#include <utility>
using namespace std;
 
typedef pair<intint> pib;
 
pair<intint> p;
 
int main(void) {
    ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
    int n;
    cin >> n;
    priority_queue<pib, vector<pib>, greater<pib> > pq;
 
    while (n--) {
        int x;
        cin >> x;
        if (x == 0) {
            if (!pq.empty()) {
                cout << pq.top().second << "\n";
                pq.pop();
            }
            else {
                cout << "0\n";
            }
        }
        else {
            pq.push({ abs(x), x });
        }
    }
    
    return 0;
}
cs

 

반응형

'알고리즘 문제풀이 > 백준' 카테고리의 다른 글

[백준 1715번] 카드 정렬하기  (0) 2020.03.11
[백준 1002번] 터렛  (0) 2020.03.11
[백준 1927번] 최소 힙  (0) 2020.03.09
[백준 11279번] 최대 힙  (0) 2020.03.09
[백준 1484번] 다이어트  (0) 2020.03.07
반응형

문제 링크: https://www.acmicpc.net/problem/1927

 

1927번: 최소 힙

첫째 줄에 연산의 개수 N(1≤N≤100,000)이 주어진다. 다음 N개의 줄에는 연산에 대한 정보를 나타내는 정수 x가 주어진다. 만약 x가 자연수라면 배열에 x라는 값을 넣는(추가하는) 연산이고, x가 0이라면 배열에서 가장 작은 값을 출력하고 그 값을 배열에서 제거하는 경우이다. 입력되는 자연수는 2^31보다 작다.

www.acmicpc.net

<문제 풀이> 우선순위 큐

priority_queue<자료형, 구현체, 비교연산자>
비교연산자에 greater<int> 넣어주면 힙을 오름차순으로 정렬

 

<C++ 소스 코드>

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
#include <iostream>
#include <queue>
using namespace std;
 
 
int main(void) {
    ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
    int n;
    cin >> n;
    priority_queue<intvector<int>, greater<int> > pq;
 
    while (n--) {
        int x;
        cin >> x;
        if (!x) {
            if (!pq.empty()) {
                cout << pq.top()<<"\n";
                pq.pop();
            }
            else {
                cout << "0\n";
            }
        }
        else {
            pq.push(x);
            
        }
    }
    
    return 0;
}
cs

 

반응형

'알고리즘 문제풀이 > 백준' 카테고리의 다른 글

[백준 1002번] 터렛  (0) 2020.03.11
[백준 11286번] 절댓값 힙  (0) 2020.03.10
[백준 11279번] 최대 힙  (0) 2020.03.09
[백준 1484번] 다이어트  (0) 2020.03.07
[백준 1806번] 부분합  (0) 2020.03.05
반응형

문제 링크: https://www.acmicpc.net/problem/11279

 

11279번: 최대 힙

첫째 줄에 연산의 개수 N(1≤N≤100,000)이 주어진다. 다음 N개의 줄에는 연산에 대한 정보를 나타내는 정수 x가 주어진다. 만약 x가 자연수라면 배열에 x라는 값을 넣는(추가하는) 연산이고, x가 0이라면 배열에서 가장 큰 값을 출력하고 그 값을 배열에서 제거하는 경우이다. 입력되는 자연수는 2^31보다 작다.

www.acmicpc.net

<문제 풀이>

priority_queue 사용

<C++ 소스 코드>

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
#include <iostream>
#include <queue>
using namespace std;
 
 
int main(void) {
    ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
    int n;
    cin >> n;
    priority_queue<int> pq;
 
    while (n--) {
        int x;
        cin >> x;
        if (!x) {
            if (!pq.empty()) {
                cout << pq.top()<<"\n";
                pq.pop();
            }
            else {
                cout << "0\n";
            }
        }
        else {
            pq.push(x);
            
        }
    }
    
    return 0;
}
cs

 

반응형

'알고리즘 문제풀이 > 백준' 카테고리의 다른 글

[백준 11286번] 절댓값 힙  (0) 2020.03.10
[백준 1927번] 최소 힙  (0) 2020.03.09
[백준 1484번] 다이어트  (0) 2020.03.07
[백준 1806번] 부분합  (0) 2020.03.05
[백준 1644번] 소수의 연속합  (0) 2020.03.05
반응형

문제 링크: https://www.acmicpc.net/problem/1484

 

1484번: 다이어트

첫째 줄부터 한 줄에 하나씩 가능한 성원이의 현재 몸무게를 오름차순으로 출력한다. 가능한 몸무게가 없을 때는 -1을 출력한다. 현재 몸무게는 자연수로 떨어지지 않을 수도 있는데, 이런 경우는 제외해야 한다.

www.acmicpc.net

<문제 풀이> 투 포인터

G = E^2 - S^2를 만족하는 E를 구하면 된다.

 

E = 1, S = 1 에서 시작

다음을 반복한다.

 

1. E^2 - S^2 > G 이면서 E - S가 1이면 반복문 종료(가장 인접한 제곱수 끼리의 차가 G보다 크면 더 이상 답을 구할 수 없다 -> 1, 4, 9, 16,.... 나열해보면 알 수 있음)


2. E^2- - S^2 > G 이면 S++


3. E^2- - S^2 <= G 이면 E++

 

<c++ 소스 코드>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
 
int main(void) {
    ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
    int g;
    cin >> g;
    long long e = 1, s = 1;
    bool existed = false;
    while (true) {
        if (e * e - s * s == g) {
            existed = true;
            cout << e << "\n";
        }
        if (e - s == 1 && e * e - s * s > g) break;
        if (e * e - s * s > g) s++;
        else e++;
    }
    if (!existed) cout << -1;
    
    return 0;
}
cs
반응형

'알고리즘 문제풀이 > 백준' 카테고리의 다른 글

[백준 1927번] 최소 힙  (0) 2020.03.09
[백준 11279번] 최대 힙  (0) 2020.03.09
[백준 1806번] 부분합  (0) 2020.03.05
[백준 1644번] 소수의 연속합  (0) 2020.03.05
[백준 2003번] 수들의 합 2  (0) 2020.03.05
반응형

문제 링크: https://www.acmicpc.net/problem/1806

 

1806번: 부분합

문제 10,000 이하의 자연수로 이루어진 길이 N짜리 수열이 주어진다. 이 수열에서 연속된 수들의 부분합 중에 그 합이 S 이상이 되는 것 중, 가장 짧은 것의 길이를 구하는 프로그램을 작성하시오. 입력 첫째 줄에 N (10 ≤ N < 100,000)과 S (0 < S ≤ 100,000,000)가 주어진다. 둘째 줄에는 수열이 주어진다. 수열의 각 원소는 공백으로 구분되어져 있으며, 10,000이하의 자연수이다. 출력 첫째 줄에 구하고자 하는 최소의 길

www.acmicpc.net

<문제 풀이> 투 포인터

투 포인터 알고리즘을 적용하면 된다.

 

left, right 포인터를 준비하고 찾은 부분합이 s이상이면 그때의 수열의 길이와 이전에 구했던 길이의 최솟값으로 갱신하고 left을 증가시키면 된다. 왜냐하면 부분합이 s이상인걸 찾았을 때 right을 증가시키면 수열의 길이가 증가하므로 확인할 필요가 없다.

 

<C++ 소스 코드>

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
#include <iostream>
#include <algorithm>
using namespace std;
 
int n, s;
int arr[100000];
int main(void) {
    ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
    cin >> n >> s;
    for (int i = 0; i < n; i++cin >> arr[i];
    int l = 0, r = 0, sum = 0, res = n;
    bool existence = false;
    while (true) {
        if (sum >= s && s) {
            existence = true;
            res = min(res, r - l);
            sum -= arr[l++];
        }
        else if (r == n) break;
        else sum += arr[r++];
    }
    if (existence) cout << res;
    else cout << 0;
    return 0;
}
cs

 

 

반응형

+ Recent posts