#문제

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

 

17298번: 오큰수

첫째 줄에 수열 A의 크기 N (1 ≤ N ≤ 1,000,000)이 주어진다. 둘째에 수열 A의 원소 A1, A2, ..., AN (1 ≤ Ai ≤ 1,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
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
#include <iostream>
#include <stack>
using namespace std;
 
int n;
int a[1000001];            // 인덱스 1~1,000,000을 사용한다 
int answer[1000001];
 
int main(){
    cin>>n;
    stack<int> st;
    // 오큰수를 판별할 수들을 a[i]에 저장한다. 
    for(int i=1; i<=n; i++){
        cin>>a[i];
    }
    
    // 수열에 들어갈 수 있는 어느 원소보다 큰 값을 스택에 push 
    st.push(1000002);
    // 수열을 뒤에서부터 앞으로 탐색한다. 
    for(int i=n; i>0; i--){
        // 스택의 top에 현재 수열값보다 작은 값이 있다면
        // 더 큰 수가 나올때까지 pop한다.
        // -> 현재 수열값 뒤쪽에 존재하는 가장 최근의 더 큰 값이 나온다. 
        if( st.top()<=a[i] ){
            while(true){
                st.pop();
                if( st.top()>a[i] ) break;
            }
        }
        // 앞에서 더 작은값이 존재해서 pop연산 진행 후에
        // 바로 a[i]의 오큰수 판단을 위해서 else대신 if문을 사용.
        // 스택 top값 > 수열값이면
        // answer[i]에 a[i]의 오큰수를 저장하고
        // a[i]를 스택에 push한다. 
        if( st.top()>a[i]){
            if( st.top()==1000002 ){
                answer[i] = -1;
            }
            else{
                answer[i] = st.top();
            }
            st.push(a[i]);
        }
    }
    
    // 수열의 오큰수를 출력한다. 
    for(int i=1; i<=n; i++){
        cout<<answer[i]<<' ';
    }
    
    return 0;
}
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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <iostream>
#include <stack>
using namespace std;
 
int n;
int a[1000001];            // 인덱스 1~1,000,000을 사용한다 
 
int main(){
    cin>>n;
    stack<int> st;
    // 오큰수를 판별할 수들을 a[i]에 저장한다. 
    for(int i=1; i<=n; i++){
        cin>>a[i];
    }
    
    // 수열에 들어갈 수 있는 어느 원소보다 큰 값을 스택에 push 
    st.push(1000002);
    // 수열을 뒤에서부터 앞으로 탐색한다. 
    for(int i=n; i>0; i--){
        // 스택의 top에 현재 수열값보다 작은 값이 있다면
        // 더 큰 수가 나올때까지 pop한다.
        // -> 현재 수열값 뒤쪽에 존재하는 가장 최근의 더 큰 값이 나온다. 
        if( st.top()<=a[i] ){
            while(true){
                st.pop();
                if( st.top()>a[i] ) break;
            }
        }
        // 앞에서 더 작은값이 존재해서 pop연산 진행 후에
        // 바로 a[i]의 오큰수 판단을 위해서 else대신 if문을 사용.
        // 스택 top값 > 수열값이면
        // tmp에 a[i]값을 보관. 
        // a[i]에 a[i]의 오큰수(스택의 top값)를 저장하고
        // tmp에 보관해둔 a[i]를 스택에 push한다. 
        if( st.top()>a[i]){
            int tmp=a[i]; 
            if( st.top()==1000002 ){
                a[i] = -1;
            }
            else{
                a[i] = st.top();
            }
            st.push(tmp);
        }
    }
    
    // 수열의 오큰수를 출력한다. 
    for(int i=1; i<=n; i++){
        cout<<a[i]<<' ';
    }
    
    return 0;
}
csd

a[i]값을 tmp에 저장해두고, a[i]에 스택의 top값을 저장,

스택에 tmp값을 push하면 answer[1000001]사이즈 배열을 추가로 사용하지 않아도 되므로 메모리 사용을 줄일 수 있다.

( 약 12000kb -> 약 8000kb 로 메모리 사용이 줄어들었음. )

##

수열의 뒤에서부터 앞으로 스택에 push하며 판단하는 것이 포인트!

'BOJ' 카테고리의 다른 글

BOJ 1966번 :: 프린터 큐  (0) 2019.12.27
BOJ 11866번 :: 조세퍼스 문제 0  (0) 2019.12.26
BOJ 1874번 :: 스택 수열  (0) 2019.12.25
BOJ 2740번 :: 행렬 곱셈  (0) 2019.12.25
BOJ 11401번 :: 이항 계수 3  (0) 2019.12.25

+ Recent posts