PS(Problem Solving)/백준(BOJ)

[백준][5430번][C/C++] AC

seongmik 2020. 12. 19. 19:48
728x90
반응형

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

 

5430번: AC

각 테스트 케이스에 대해서, 입력으로 주어진 정수 배열에 함수를 수행한 결과를 출력한다. 만약, 에러가 발생한 경우에는 error를 출력한다.

www.acmicpc.net

AC라는 새로운 언어를 사용하여 정수 배열을 다루는 연산을 해주는 걸 처리하는 문제이다.

 

AC언어는 'R'과 'D'로 이루어진 언어이다.

R함수는 정수 배열을 뒤집는다.

D함수는 정수 배열의 첫 번째 숫자를 버린다.

 

이 두 가지 연산을 하는 문제인데 생각보다 까다로운 부분이 두 가지 정도 있다.. 

1. 정수 배열을 정수를 띄어쓰기로 구분해서 주는 것이 아니라 문자열 형식으로 준다.

2. 정수 배열의 크기가 최대 100,000인데 명령이 100,000번까지 들어올 수 있으므로 R함수를 처리할 때마다 정수 배열을 뒤집으면 TLE가 난다.

 

이 두가지 문제를 해결하는 방법은 다음과 같다.

1. <cstdlib>또는 <stdlib.h> 헤더에 들어있는 atoi 함수를 사용하여 입력받은 문자열을 정수로 바꾼다. (atoi 함수를 모른다면 atoi 함수에 대해서 공부해보고 풀기!)

2. 정수 배열을 실제로 뒤집는 것이 아니라 deque를 이용하여 뒤집은 것 같은 효과를 낸다.

이 두가지 해결책에 유의해서 문제를 풀면 문제의 큰 틀은 잡힌 것이다.

 

단 이 문제의 정답률이 글 쓰는 시점 기준 20%로 낮은 것으로 보아 자잘한 실수를 할만한 부분이 많은듯하니 사소한 부분을 꼼꼼히 체크해주는 게 중요해 보인다.

1. 배열 크기 주의! - 배열 크기가 감이 안 오면 일단 500,000 정도로 크게 잡는 것도 나쁘지 않다.(대체로 문제들의 배열 크기가 int형 기준 최대 500,000 안에서 끊기는 편임)

2. 문제 풀 때 시간 복잡도 생각하기! - 코드가 길어지다 보면 이상한 데서 시간 복잡도를 생각 못해서 TLE날 때가 있다.

3.  한 번에 여러 가지 테스트 케이스가 들어가는 만큼 배열, 변수 초기화에 주의! - 애초에 테케 시작할 때 변수를 선언해주는 것도 나쁘지 않다.

문제를 더럽게 풀어서 딱히 할말은 없지만 문자열을 많이 다뤄본 편이 아니라 입력이 문자열과 섞여서 복잡하게 주어지면 코드가 지저분해지는 것 같다..

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
using namespace std;
bool mode=true; //true일 때 왼쪽에서부터 읽기, false일 때 오른쪽에서부터 읽기

void rvs() { // 모드를 바꾸는 함수
    if(mode==true) {
        mode=false;
        return;
    }
    else {
        mode=true;
        return;
    }
}

int main() {
    int T;
    scanf("%d",&T);
    while(T--) {
        char str[100002], num[500000]; // 선언부
        int N, endad=0;
        bool er=false;
        deque<int> dq;
        mode=true;
        memset(num,NULL,sizeof(num));
        
        scanf("%s",str); // 입력부1
        scanf("%d",&N);
        scanf("%s",num);
        
        if(N!=0) // 입력부2
        {
            for(int i=0;i<sizeof(num);i++) {
                if(num[i]=='[' || num[i]==',') {
                    dq.push_back(atoi(&num[i+1]));
                }
                else if(num[i]==']') break;
            }
        }
        
        for(int i=0;i<sizeof(str);i++) { //처리부
            if(str[i]=='R') {
                rvs();
            }
            else if(str[i]=='D') {
                if(dq.size()!=0) {
                    if(mode==true) dq.pop_front();
                    else dq.pop_back();
                }
                else {
                    printf("error\n");
                    er=true;
                    break;
                }
            }
            else break;
        }
        
        if(er) continue;
        
        int dqnum=dq.size();
        printf("["); // 출력부
        if(mode==true) {
            for(int i=0;i<dqnum;i++) {
                printf("%d",dq.front());
                dq.pop_front();
                if(i!=dqnum-1) printf(",");
            }
        }
        else {
            for(int i=0;i<dqnum;i++) {
                printf("%d",dq.back());
                dq.pop_back();
                if(i!=dqnum-1) printf(",");
            }
        }
        printf("]\n");
    }
    
    return 0;
}
728x90
반응형