Skip to content

Commit

Permalink
[feat] contents 추가
Browse files Browse the repository at this point in the history
  • Loading branch information
suu3 committed Dec 18, 2023
1 parent 288e98e commit 35f4188
Show file tree
Hide file tree
Showing 5 changed files with 277 additions and 2 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
- name: Install dependencies
run: pnpm install
- name: Build
run: pnpm clean && pnpm build
run: pnpm clean && pnpm run build
env:
NODE_ENV: production
- uses: peaceiris/actions-gh-pages@v2
Expand Down
109 changes: 109 additions & 0 deletions content/blog/Tistory/[C++ 백준 17928] 오큰수.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
---
title: [C++/백준 17928] 오큰수
date: "2022-08-29"
description: "[C++/백준 17928] 오큰수 문제 풀이"
tag: ["algorithm"]
---

## 문제

크기가 N인 수열 A = A1, A2, ..., AN이 있다. 수열의 각 원소 Ai에 대해서 오큰수 NGE(i)를 구하려고 한다. Ai의 오큰수는 오른쪽에 있으면서 Ai보다 큰 수 중에서 가장 왼쪽에 있는 수를 의미한다. 그러한 수가 없는 경우에 오큰수는 -1이다.

예를 들어, A = [3, 5, 2, 7]인 경우 NGE(1) = 5, NGE(2) = 7, NGE(3) = 7, NGE(4) = -1이다. A = [9, 5, 4, 8]인 경우에는 NGE(1) = -1, NGE(2) = 8, NGE(3) = 8, NGE(4) = -1이다.

### 첫 번째 코드 (38% 시간초과)

```jsx
#include <iostream>
#include <stack>

using namespace std;

int main()
{
ios_base :: sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);

int n;
int input;

stack<int> st;
stack<int> less;

cin >> n;
int arr[n];

for(int i = 0 ; i < n ; i++){
cin >> arr[i];
}
for(int i = n-1 ; i >=0 ; i--){
st.push(arr[i]);
}

for(int i = 0 ; i < n ; i++){
int cur = arr[i];
st.pop();
if(st.empty()){
cout << "-1 ";
continue;
}

while(!st.empty()){
if(cur < st.top()){
cout << st.top() <<" ";
while(!less.empty()){
st.push(less.top());
less.pop();
}
break;
}else{
less.push(st.top());
st.pop();

if(st.empty()){
cout << "-1 ";
while(!less.empty()){
st.push(less.top());
less.pop();
}
break;

}
}
}
}

return 0;
}
```

골드 4, 시간제한 1초, N 100만 에서 시간복잡도를 신경써야하는 문제임을 알 수 있었다...

처음에 짠 코드는 스택 두개와 입력받은 수열 배열을 만들어놓고, 수열의 맨 왼쪽부터 체크해서

수열이 3 5 2 7 이면 스택 하나에는 3 5 2 7 이렇게 넣어놓고 시작했다.

현재 원소가 3이면, 먼저 스택의 맨 위(=자기 자신)를 pop 한 다음 (5 2 7)

자신보다 작으면 less 스택에 넣고, 자신보다 크면 출력 후 less 배열 원소들을 다시 stack으로 넣어서 복구 시켜줬다.

왼쪽부터 시작하는 게 왼쪽에 있는 가장 큰 수를 빨리 찾을 수 있을거라 생각하고 알고리즘을 짰지만

스택 두 개를 두고 매 경우마다 복구시켜주면서 for과 while문이 중첩되었고 역시나 38%에서 시간초과가 났다 ^^;

스택 하나로 해결할 수 있는 방법이 필요했다.

### 통과 코드

첫번째 시도때는 모든 원소를 스택에 넣어놓고 하나씩 제거해갔는데,

수열의 오른쪽부터 체크하면서 스택에 원소를 추가하는 식으로 과정이 더 간단해졌다.

수열의 오른쪽부터 체크하면서 스택의 맨 위 원소가 수열보다 크면 출력하고, 작으면 제거하고, 스택이 비었으면 오큰수가 없으므로 -1을 출력한다.

오른쪽에 있는 애들 중, 자기자신보다 크면서 가장 왼쪽에 있는 애를 찾는 문제이기 때문에

오른쪽 -> 왼쪽으로 가면서 자기자신보다 작은 애들은 스택에서 제거하고 다음 차례로 넘기니

매차례 스택을 복구 시켜줬던 첫번째 시도보다 시간도 줄어들고 코드도 깔끔해졌다.
95 changes: 95 additions & 0 deletions content/blog/Tistory/[C++ 백준 2110] 공유기 설치.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
---
title: [C++/백준 2110] 공유기 설치
date: "2022-09-14"
description: "[C++/백준 2110] 공유기 설치 문제 풀이"
tag: ["algorithm"]
---

```jsx
#include <iostream>
#include <algorithm>
using namespace std;

int home[200001];
int ans = 0;

void binary_search(int n, int c){

int l = 0;
int r = home[n-1] - home[0];

while(1){
if(l > r){
return;
}

int mid = (l + r) / 2;
// 거리를 mid 이상으로 해서 몇개의 공유기를 설치할 수 있는가?
int count = 1;

int compare = home[0];
for(int i = 1 ; i < n ; i ++){
if(home[i] - compare >= mid){
count++;
compare = home[i];
}
}

if(count < c){ //설치할 수 없다. 거리를 줄이자.
r = mid - 1;
}else{ //설치할 수 있다. 거리를 늘린다.
l = mid + 1;
ans = max(ans, mid);
}
}
}

int main()
{
ios_base :: sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);

int n, c;
cin >> n >> c;

for(int i = 0 ; i < n ; i++){
cin >> home[i];
}
sort(home, home + n);

binary_search(n, c);

cout << ans;

return 0;
}
```

이분 탐색 중 parametric search 문제이다.

집 좌표 범위  (0 ≤ xi ≤ 1,000,000,000) 를 보고 시간초과가 관건이겠군 하고 이분 탐색 힌트를 얻을 수 있을 것 같다.

+) 나는 뭔가 거리를 가능한 크게 하여~ 가장 인접한 거리를 최대로~ 등등 최대로 하라는거냐 최소로 하라는거냐 어캐 풀라는거지 싶으면 parametric search를 떠올린다

parametric search를 떠올렸으면 문제를 **가능한 \_\_중에서 최대 값을 구하는 문제**로 바꾼다.

여기서는 공유기를 설치할 수 있는 거리 중에서 최대 값을 구하는 문제로 바꿨다.

범위 (l 과 r 사이)는 최대한 크게 잡는다.

구하는 값을 이분 탐색의 mid로 둔다. 여기서는 공유기 사이의 거리를 mid로 두었다.

parametric search에서 주의할 점은 공유기가 3개 있고, 각 거리마다 설치할 수 있는 공유기의 개수(count)를 셌을 때

3개보다 **더 많이 설치할 수 있어도 답이 될 수 있다**는 것이다.

그래서 count == C(문제에서 주어진 공유기의 개수)인 경우와 count > C인 경우를 나누지 않고 같이 묶었다.

공유기를 설치할 수 있는 거리를 찾았다고 그대로 끝내는 것이 아니라, 더 최적화된 답을 찾을 수 있는 가능성이 남아있으므로거리를 의미하는 mid가 커지는 방향으로, 즉, l을 늘려서 범위를 좁히는 방향으로 탐색을 더 진행한다.

거리를 mid 이상으로 했을 때 공유기를 최대 몇 개 설치할 수 있는지 구하는 부분이 고민이었는데,

1 2 4 8 9 가 있을 때 꼭 공유기를 1에 설치해야하는지에 대한 확신이 없어서 이중 for문으로 시작점을 옮겨가며 count 했더니 시간초과가 났다.

생각해보니 어차피 1에 공유기를 설치하는 게 1을 건너뛰고 2에 공유기를 설치하는 경우를 포함하므로 1부터 시작하는게 맞았다. for문을 하나로 바꾸고 통과했다.
71 changes: 71 additions & 0 deletions content/blog/Tistory/[C++ 백준 5052] 전화번호 목록.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
---
title: [C++/백준 5052] 전화번호 목록
date: "2022-09-14"
description: "[C++/백준 5052] 전화번호 목록 문제 풀이"
tag: ["algorithm"]
---

```jsx
//5052 전화번호 목록
#include <iostream>
#include <algorithm>

using namespace std;


int main()
{
ios_base :: sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);

int t;
cin >> t;
while(t--){
int n;
cin >> n;
string phone[n];
for(int i = 0 ; i < n ; i++){
cin >> phone[i];
}
sort(phone, phone + n);

string compare = phone[0];

bool consistent = true;
for(int i = 1 ; i < n ; i++){
bool check;
if(compare.length() > phone[i].length()){
check = (compare.substr(0, phone[i].length()) == phone[i]);
}else{
check = (compare == phone[i].substr(0, compare.length()));
}

if(check){
cout << "NO\n";
consistent = false;
break;
}
compare = phone[i];

}

if(consistent){
cout << "YES\n";
}

}

return 0;
}
```

나는 이문제가 왜 골드 4인지 모르겠다 트라이 안쓰고 그냥 정렬해도 풀리는데..

같은 문자열 문제 중에 1141 접두사 실버2 문제가 있는데 이게 더 어려웠던 거 같다.

그냥 한 번 정렬해준 다음, 앞에서부터 두개씩 비교해가며

한쪽이 남은 한쪽의 접두사가 되는지 체크하는 check라는 bool 변수를 썼고,

check가 true일 때 일관성을 의미하는 변수 consistent를 false로 바꿔줬다.
2 changes: 1 addition & 1 deletion src/constants/page.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export const POST_PER_PAGE = 1
export const POST_PER_PAGE = 10

0 comments on commit 35f4188

Please sign in to comment.