알고리즘

20/04/03

openingsound 2020. 4. 3. 02:10

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

 

11003번: 최솟값 찾기

N개의 수 A1, A2, ..., AN과 L이 주어진다. Di = Ai-L+1 ~ Ai 중의 최솟값이라고 할 때, D에 저장된 수를 출력하는 프로그램을 작성하시오. 이때, i ≤ 0 인 Ai는 무시하고 D를 구해야 한다.

www.acmicpc.net

슬라이딩~ 윈도우

덱 안에 새로운 값을 push_back할때 넣기전 back값이 넣으려는값 이하이면 빼준다!

넣으려는 값을 A라고하고 맨뒤에 있는 값을 B라고 하면 A와 B가 같이 있을때 B를 선택할 경우에 항상 A를 선택하면 되기 때문이다. 따라서 모든 값을 deque에 넣었다 빼면 됨으로 O(N)으로 된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
deque<pii> dq;
vector<int> v;
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    
    int a, b;
    cin >> a >> b;
    for (int i = 0; i < a; i++) {
        int tem;
        cin >> tem;
        v.push_back(tem);
    }
    for (int i = 0; i < a; i++) {
        while (!dq.empty() && dq.back().first >= v[i]) {
            dq.pop_back();
        }
        dq.push_back({ v[i],i });
        if (dq.front().second == i - b)
            dq.pop_front();
        cout << dq.front().first << ' ';
    }
}
 
 

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

 

2003번: 수들의 합 2

첫째 줄에 N(1≤N≤10,000), M(1≤M≤300,000,000)이 주어진다. 다음 줄에는 A[1], A[2], …, A[N]이 공백으로 분리되어 주어진다. 각각의 A[x]는 30,000을 넘지 않는 자연수이다.

www.acmicpc.net

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
vector<int> v;
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    
    int a, b;
    cin >> a >> b;
    for (int i = 0; i < a; i++) {
        int tem;
        cin >> tem;
        v.push_back(tem);
    }
    int ans = 0;
    int tem = 0;
    int l = 0, r = 0;
    for (int i = 0; i < a; i++) {
        tem += v[i];
        while (tem > b) {
            tem -= v[l];
            l++;
        }
        if (tem == b)ans++;
    }
    cout << ans;
}
 

입력받으면서 바로 처리해도 됨

 

 

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

 

1644번: 소수의 연속합

문제 하나 이상의 연속된 소수의 합으로 나타낼 수 있는 자연수들이 있다. 몇 가지 자연수의 예를 들어 보면 다음과 같다. 3 : 3 (한 가지) 41 : 2+3+5+7+11+13 = 11+13+17 = 41 (세 가지) 53 : 5+7+11+13+17 = 53 (두 가지) 하지만 연속된 소수의 합으로 나타낼 수 없는 자연수들도 있는데, 20이 그 예이다. 7+13을 계산하면 20이 되기는 하나 7과 13이 연속이 아니기에 적합한 표현이 아니다. 또한 한

www.acmicpc.net

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
bool che[MAXN];
vector<int> v;
void arra(int a) {
    for (int i = 2; i <= sqrt(a); i++) {
        if (che[i]) continue;
        for (int j = 2 * i; j <= a; j += i) {
            che[j] = 1;
        }
    }
    for (int i = 2; i <= a; i++) {
        if (che[i] == 0) v.push_back(i);
    }
}
 
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    int a;
    cin >> a;
    arra(a);
    int l = 0;
    int ans = 0;
    int tem = 0;
    for (int i = 0; i < v.size(); i++) {
        tem += v[i];
        while (tem > a) {
            tem -= v[l];
            l++;
        }
        if (tem == a)
            ans++;
    }
    cout << ans << '\n';
}
 
 

윗 문제에 아리스토 텔리스의 체 를 추가하면 됨 

 

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
const int MAXN = 100005;
 
int arr[MAXN];
 
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    int a, b;
    cin >> a >> b;
    int sum = 0, ans = 1000040,l = 0;
    for (int i = 0; i < a; i++) {
        cin >> arr[i];
        sum += arr[i];
        while (sum >= b) {
            ans = min(ans, i - l + 1);
            sum -= arr[l];
            l++;
        }
    }
    if (ans == 1000040cout << 0;
    else cout << ans;
}
 
 

조건 부분을 살짝 바꾸면됨

 

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

 

2230번: 수 고르기

첫째 줄에 두 정수 N, M(0≤M≤2,000,000,000)이 주어진다. 다음 N개의 줄에는 차례로 A[1], A[2], …, A[N]이 주어진다. 각각의 A[i]는 0 ≤ |A[i]| ≤ 1,000,000,000을 만족한다.

www.acmicpc.net

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include<iostream>
 
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    int a, b;
    cin >> a >> b;
    int ans = 2000000000;
    for (int i = 0; i < a; i++) {
        cin >> arr[i];
    }
    sort(arr, arr + a);
    int l = 0;
    for (int i = 0; i < a; i++) {
        while (arr[i] - arr[l] >= b) {
            ans = min(ans, arr[i] - arr[l]);
            l++;
        }
    }
    cout << ans;
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
 

똑 같 다

 

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

 

1484번: 다이어트

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

www.acmicpc.net

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
const int MAXN =50006;
 
int arr[MAXN];
 
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    int a;
    cin >> a;
    for (int i = 1; i < MAXN; i++) {
        arr[i] =  i * i;
    }
    int l = 1;
    vector<int> v;
    for (int i = 1; i < MAXN; i++) {
        while (arr[i] - arr[l] > a) {
            l++;
        }
        if (arr[i] - arr[l] == a) v.push_back(i);
    }
    if (v.empty())cout << -1;
    else {
        for (int a : v)
            cout << a << "\n";
    }
}
 
 

MAXN을 100'000까지 다 안봐도 된다 i^2- (i-1)^2 = 2*i-1이기 때문!

비슷 하다

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

20/04/08 USACO 유사코 1월 실버  (2) 2020.04.08
20/04/06 유사코  (0) 2020.04.07
20/04/02  (0) 2020.04.02
20/03/30  (0) 2020.03.30
20/03/23  (0) 2020.03.25