[백준-node.js-5430] AC

이태헌·2023년 6월 16일
0
post-thumbnail

문제

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

풀이(첫번째 시도 시간 초과)

let input = require('fs').readFileSync('/dev/stdin').toString().trim().split('\n')
let N = input.shift();
    
    let answer = [];
    for(let i = 1; i<input.length; i+=3){
      
      let roof = input[i-1].split('')
      let arr = JSON.parse(input[i + 1]);
      let rCnt = 0;
      let dCnt = 0;

      for(let x of roof){
        if(x==='R') rCnt++;
        else dCnt++;
      }
      
      if(rCnt%2 !== 0){
        arr.reverse()
      }
      
      let lenTF = false;
        for(let i = 0; i<dCnt; i++){
          if(arr.length != 0){
            arr.shift()
          }else{
            lenTF = true;
            answer.push('error')
          }
        }
      if(!lenTF) answer.push('['+String(arr)+']')
    }
      console.log(answer.join('\n'))

for문 안에서 reverse함수를 사용하다보니 시간초과가 난거 같았다. roof안의 R의 갯수를 세어서 reverse함수를 한번만 해줬는데 시간초과가 나서 reverse에서 났을수도 있고 이중포문을 돌려서 그런거 일수도 있다고 생각했다.

두번째 풀이

let input = require('fs').readFileSync('/dev/stdin').toString().trim().split('\n')
let N = input.shift();
    
    let answer = [];
    for(let i = 1; i<input.length; i+=3){
      
      let roof = input[i-1].split('')
      const arr = JSON.parse(input[i + 1]);
            
      let isRevers = false;
      let lenTF = false;

      for(let x of roof){  // 1
        if(x==='R') {
          isRevers = !isRevers 
        }
        else if(x==='D'){ // 2
          if(arr.length >0){
            if(isRevers) arr.pop()
            else arr.shift()
          }else{
            lenTF = true;
            answer.push('error')
            break;
          }
        }
      }
      if(!lenTF) answer.push(JSON.stringify(isRevers ? arr.reverse():arr)) // 3
    }
    
    console.log(answer.join('\n'))
  1. 첫번째로 roof에 들어가있는 문자열을 돌면서 R이면 isReverse를 바꿔준다
  2. D이면 arr의 문자열이 0보다 크면 배열이 있는것이므로 isReverse함수에 따라서 앞에서 뺄지 뒤에서 뺼지를 정해준다. 만약에 arr0이면 lenTF를 바꿔주고 answererror를 넣어준다.
  3. lenTF에 따라서 error가 들어갔는지 안들어갔는지를 체크하고 안들어간 경우면 answerisReverse를 검사한 arr을 넣어준다.

다른 사람의 풀이

const fs=require('fs');
const input=fs.readFileSync('/dev/stdin').toString().split('\n');
const count=+input[0];
let arr=[];
for(let i=0;i<count;i++){
    let p=input[i*3+1];
    let n=+input[i*3+2];
    let array=JSON.parse(input[i*3+3])
    arr.push({p,n,array});
}
let result=arr.map(({p,n,array})=>{
    let [left,right]=[0,n];
    let dir=true;
    for(let i=0;i<p.length;i++){
        if(p[i]==='D'){
            if(dir) left++;
            else right--;
            if(left>right) return 'error';
        }else{
            dir=!dir;
        }
    }
        if(dir){
            return JSON.stringify(array.slice(left,right))
        }else{
            return JSON.stringify(array.slice(left,right).reverse())
        }
})
for(let i=0;i<count;i++){
    console.log(result[i]);
}

left,right를 이용하여서 shift, pop을 사용하지않고 계산하여서 수행시간이 굉장히 짧았다.
D가 나왔을때 isReverse(여기선 dir)이 참이면 앞에서 빼는것이므로 left의 숫자를 ++해주고 아니라면 뒤에서 빼야하므로 right의 숫자를 --해준다. 예를 들어서 (1,2,3,4)가 있고 isReversetrue이면 앞에서 뺴는데 예를 들어 D가 2개가 있다면 left는 현재 2가 된다. 이후에 배열을 slice 함수로 잘라서 리턴하게 되면 (3,4)가 들어가는 형태이다.

시간복잡도를 처음에 계산을 하고 코딩을 시작하면 여러번 수정하거나 아예 코드 자체를 바꾸는 불상사를 줄일 수 있을거 같다.

0개의 댓글