백준 3015 오아시스 재결합 c++
[문제 링크]
https://www.acmicpc.net/problem/3015
[입출력 예]
입력 | 출력 |
---|---|
7 2 3 1 2 2 5 1 |
10 |
[1차시도 - 실패]
#include <bits/stdc++.h> using namespace std; #define ll long long #define X first #define Y second ll a[500000]; int main(){ ios::sync_with_stdio(0); cin.tie(0); ll answer=0; int n; cin>>n; stack <pair<ll,int>> s; pair<ll,int>max_pair ={(ll)INT_MAX +1,n}; s.push(max_pair); //배열에 대입. for (int i=0; i<n; i++){ cin>>a[i]; } //반복문으로 오큰수처럼 풀이 for (int i=n-1; i>=0; i--){ // stack의 탑보다 큰 경우 -> top보다 요소가 작을때까지 top 빼기. if (s.top().X<a[i]){ while(s.top().X < a[i]){ s.pop(); answer+=1; } if (s.top().Y!=n)answer+=1; s.push({a[i],i}); } // stack의 탑보다 작은 경우 else if (s.top().X>a[i]){ s.push({a[i],i}); if (i != n-1)answer+=1; } else { int tmpIdx; while(s.top().X==a[i]){ tmpIdx=s.top().Y; s.pop(); } answer+=tmpIdx-i; if (s.top().Y!=n) answer+=1; s.push({a[i],tmpIdx}); } } cout<<answer; return 0; } // 이런 풀이로 풀 수가 없다. // 이 풀이는 인덱스만 가지고 푸는 건데, 그렇게 푼다는 건 스택 안에 전조증가 수열로 남긴다는 것이다. // 근데 그렇게 풀면 똑같은 키가 여러 번 나올 때 하나하나 다 세주기가 어렵게 된다. // 그래서 몇번 반복되는지를 반드시 변수로 세서 넣어줘야 한다...
[소스코드]
#include <bits/stdc++.h> using namespace std; #define X first #define Y second int main(void) { ios::sync_with_stdio(0); cin.tie(0); int n; cin >> n; stack<pair<int, int>> S; long long ans = 0; while (n--) { int h; cin >> h; int cnt = 1; while (!S.empty() && S.top().X <= h) { ans += S.top().Y; if (S.top().X == h) cnt += S.top().Y; S.pop(); } if (!S.empty()) ans++; S.push({h, cnt}); } cout << ans; } // [문제 해설] // 1. 스택에는 이전까지의 키가 내림차순으로 쌓이게 된다. // 2. 스택에 아무것도 없는 상황에서 새로운 데이터를 만난 경우, 스택에 데이터와 기본카운트 1을 넣는다. // 3. 새롭게 만난 데이터가 스택의 top보다 크거나 같은 경우, stack의 top의 cnt를 더한다. // 4. cnt는 해당 키를 가진 인물이 스택 속에 연속적으로 몇명이나 있는가.. 를 의미하는 것과 같다. // 5. 새롭게 만난 데이터가 스택의 top보다 크다면, 그 데이터보다 큰 top이 나올 때까지 pop을 수행한다. // 6. 그런데 이때, 새롭게 만난 데이터(h)와 stack의 탑이 같다면, 카운트를 올려줘서 새로운 데이터에 해당하는 값이 연속몇번인지 센다. // 7. 뽑다 보면 경우의 수는 2가지로 나뉘는데, 끝가지 스택을 비워버리거나, 스택의 어떤 값에 막히는 경우일 것이다. // 8. 만약 어떤 값에 막히는 경우라면(not empty) 그 사람을 볼 수 있는 상황이므로 ans에 하나 값을 더한다. // 9. 끝가지 다 뽑았으면 끝까지 다 본 것이므로 ans를 조작하지 않는다. // 10. 현재 해당하는 h값을 연속하는 회수 cnt와 함께 스택에 넣는다.
[출처]
https://github.com/encrypted-def/basic-algo-lecture/blob/master/0x05/solutions/3015.cpp
'PS > BOJ' 카테고리의 다른 글
백준 10845 큐,큐2 c++ (0) | 2022.02.01 |
---|---|
백준 6549 히스토그램에서 가장 큰 직사각형 풀이 c++ (0) | 2022.01.25 |
백준 17298 오큰수 c++ (0) | 2022.01.13 |
백준 6918 옥상 정원 꾸미기 c++ (0) | 2022.01.13 |
백준 1874 스택수열 c++ (0) | 2022.01.08 |
댓글
이 글 공유하기
다른 글
-
백준 10845 큐,큐2 c++
백준 10845 큐,큐2 c++
2022.02.01 -
백준 6549 히스토그램에서 가장 큰 직사각형 풀이 c++
백준 6549 히스토그램에서 가장 큰 직사각형 풀이 c++
2022.01.25 -
백준 17298 오큰수 c++
백준 17298 오큰수 c++
2022.01.13 -
백준 6918 옥상 정원 꾸미기 c++
백준 6918 옥상 정원 꾸미기 c++
2022.01.13
댓글을 사용할 수 없습니다.