항해 99클럽 코테

99클럽 코테 스터디 17일차 TIL

metamong-data 2024. 11. 14. 10:45
728x90
반응형

오늘의 학습 키워드

스택/큐

과제

문제

임스는 연계 기술을 사용하는 게임을 플레이 중에 있다. 연계 기술은 사전 기술본 기술의 두 개의 개별 기술을 순서대로 사용해야만 정상적으로 사용 가능한 기술을 말한다.

하나의 사전 기술은 하나의 본 기술과만 연계해서 사용할 수 있으며, 연계할 사전 기술 없이 본 기술을 사용했을 경우에는 게임의 스크립트가 꼬여서 이후 사용하는 기술들이 정상적으로 발동되지 않는다. 그렇지만 반드시 사전 기술을 사용한 직후에 본 기술을 사용할 필요는 없으며, 중간에 다른 기술을 사용하여도 연계는 정상적으로 이루어진다.

임스가 사용할 수 있는 기술에는 1$1$9$9$, L$L$, R$R$, S$S$, K$K$가 있다. 1$1$9$9$는 연계 없이 사용할 수 있는 기술이고, L$L$은 R$R$의 사전 기술, S$S$은 K$K$의 사전 기술이다.

임스가 정해진 순서대로 N$N$개의 기술을 사용할 때, 기술이 몇 번이나 정상적으로 발동하는지를 구해보자.

단, 연계 기술은 사전 기술본 기술 모두 정상적으로 발동되었을 때만 하나의 기술이 발동된 것으로 친다.

입력

첫 번째 줄에는 총 기술 사용 횟수 N$N$이 주어진다. (1≤N≤200000$1 \le N \le 200,000$)

두 번째 줄에는 임스가 사용할 N$N$개의 기술이 공백 없이 주어진다.

출력

임스가 정상적으로 기술을 사용한 총 횟수를 출력한다.

예제 입력 1

5
S12K2

예제 출력 1

4

 1$1$, 2$2$, S$S$ - K$K$, 2$2$로 스킬을 성공적으로 총 4번 사용했다.

예제 입력 2

4
1LKR

예제 출력 2

1

 1$1$로 스킬을 성공적으로 1번 사용했다.

 L$L$ - R$R$로 스킬이 사용이 가능하나, 중간에 연계되어 사용돼야 하는 K$K$가 있어 성공적으로 사용이 불가능하다.

예제 입력 3

4

SSKK

예제 출력 3

2

 S$S$를 2번 연속 사용하고, K$K$를 2번 사용하여 스킬을 성공적으로 2번 사용했다.

풀이 과정

  1. 사용한 기술 총 횟수 받기
  2. 사전 기술 L,S 의 사용 횟수 초기화
  3. 사전 기술 L일 경우 L +1
  4. 본 기술 R일 경우에 L의 사용 횟수가 0보다 크면 총 횟수 +1, L는 -1 아니면 break
  5. 사전 기술 S의 경우 S +1
  6. 본 기술 K일 경우에 S의 사용 횟수가 0보다 크면 총 횟수 +1, S의 횟수 -1 아니면 break

    제출 코드 (python)

N = int(input())
skill = input()
cnt = 0    
Ls, Ss = 0, 0    

for i in skill :
    if i == 'L' :    
        Ls += 1
    elif i == 'R' :    
        if Ls > 0 :
            cnt += 1    
            Ls -= 1    
        else :        
            break    
    elif i == 'S' :    
        Ss += 1
    elif i == 'K' :
        if Ss > 0 :    
            cnt += 1    
            Ss -= 1    
        else :        
            break
    else :    
        cnt += 1

print(cnt)

다른 언어로 문제 풀기

GO 언어

package main

import (
    "bufio"
    "fmt"
    "os"
)

func main() {
    reader := bufio.NewReader(os.Stdin)
    writer := bufio.NewWriter(os.Stdout)
    defer writer.Flush()

    var N int
    fmt.Fscan(reader, &N)

    var skill string
    fmt.Fscan(reader, &skill)

    cnt := 0
    Ls, Ss := 0, 0

    for _, i := range skill {
        switch i {
        case 'L':
            Ls++
        case 'R':
            if Ls > 0 {
                cnt++
                Ls--
            } else {
                goto end  // break가 루프만 벗어나므로 goto 사용
            }
        case 'S':
            Ss++
        case 'K':
            if Ss > 0 {
                cnt++
                Ss--
            } else {
                goto end
            }
        default:
            cnt++
        }
    }

    end:
    fmt.Fprintln(writer, cnt)
}

C++

#include <iostream>
#include <string>
using namespace std;

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

    int N;
    string skill;
    cin >> N >> skill;

    int cnt = 0;
    int Ls = 0, Ss = 0;

    for(char i : skill) {
        switch(i) {
            case 'L':
                Ls++;
                break;
            case 'R':
                if(Ls > 0) {
                    cnt++;
                    Ls--;
                } else {
                    goto end;  // break 대신 goto 사용
                }
                break;
            case 'S':
                Ss++;
                break;
            case 'K':
                if(Ss > 0) {
                    cnt++;
                    Ss--;
                } else {
                    goto end;
                }
                break;
            default:
                cnt++;
        }
    }

    end:  // goto 라벨
    cout << cnt << '\n';

    return 0;
}

오늘의 회고

  • 조건이 까다로워서 생각보다 시간이 걸렸던 것 같다

출처 :https://www.acmicpc.net/problem/25497

728x90