본문 바로가기

알고리즘/백준

17608 막대기

이 문제를 처음 봤을 때에는 단순히 최댓값 구하는 문제인 줄 알고 후다닥 적었다가 당연히 틀렸다.

그럴 리가 없었는데... 아무튼 내가 생각한 풀이와 스택을 이용해서 푸는 거 두개를 적을려고 한다.

 

1. 내가 생각한 풀이

0~n-1까지 입력을 받으면서 가장 긴 막대기의 위치를 구한다.

가장 긴 막대기와 마지막 막대 사이에 있는 막대기(i번째 막대기라고 하자)를 하나하나 보면서 i번째 막대기가 가장 긴 막대기보다는 작고 마지막 막대보다는 크면 조건을 만족하는 막대기라고 생각했다. (count++해주었다)

여기서 고려했던 점은 가장 긴 막대기와 마지막 막대의 길이가 같을 때(가장 긴 막대가 마지막 막대가 되어도 상관없다)에는 count를 1만 더해주고, (사실 이 경우에는 조건을 만족하는 막대기가 그냥 1개이다)

가장 긴 막대기가 마지막 막대기보다 길 때는 count에 2를 더해주었다는 점이다. 

틀렸다고 나오는데 난 이유를 모르겠다,, 엉엉 시간초과인건지 아예 풀이에 문제가 있는 건지 모르겠다.

 

코드 : 

#include <iostream>
int a[100001];
using namespace std;

int main(){
int n, max=0;
cin>>n;
for(int i=0;i<n;i++){
cin>>a[i];
if(a[max]<a[i]) max=i;
}

int count;
if(a[max]==a[n-1]) count=1;
else if(a[max]>a[n-1]) count=2; 
for(int i=max;i<n-1;i++){
if(a[i]<a[max] && a[i]>a[n-1]) count++;
}

cout<<count;
}

 

2. 스택을 이용한 풀이

스택을 이용한 풀이는 감이 잘 잡히지 않아서 풀이를 참고하였다. : tunafish78.tistory.com/98 감사합니다,,

스택을 이용한 풀이는 막대기 하나를 넣으면서 넣는 막대기보다 작은(조건을 만족하지 않는 막대기)는 모두 pop하는 방식이다. 막대기 하나를 넣을 때 순서대로 pop만 하면 되는 이유는 이전 막대기를 넣을 때 그에 맞지 않는 막대기는 모두 pop당했기 때문이다. 약간 재귀의 느낌이 나만 난 것 같기는 하지만 어쨌든 그래서 i번째 막대기를 고려할때는 이미 이전 막대기까지 최적의 상태로 고려된 상태이므로 뭔가 더 고려하려고 노력하지 않아도 된다.

 

코드 : 

#include <iostream>

#include <stack>

using namespace std;

 

int a[1000001];

 

int main(){

int n;

cin>>n;

for(int i=0;i<n;i++) cin>>a[i];

 

stack<int> s;

for(int i=0;i<n;i++){

if(i==0) s.push(a[i]);

else{

while(!s.empty() && a[i]>=s.top(); i>=0){

s.pop();

}

s.push(a[i]);

}

}

cout<<s.size()<<endl;

}

 

'알고리즘 > 백준' 카테고리의 다른 글

2812 크게 만들기  (0) 2021.10.31
11053 가장 긴 증가하는 부분 수열  (0) 2021.08.13
11726 2xn 타일링  (0) 2021.04.26
char string 인풋받는거  (0) 2021.04.04