백준에 시작하고 이제 겨우 입문에 성공한거 같다.

많이 풀었던 실버5단계에서는 무언가를 구현하는 문제가 많았다.

따라서 어떠한것을 어떻게하면 만들 수 있는지, 어떻게하면 효율적으로 만들 수 있는지에대해 많이 고민했다.

 

하지만 최근에 실버4문제를 몇개 풀어보면서 기존의 생각방식대로는 문제를 풀어나갈 수 없겠구나 싶었다.

문제의 데이터를 어떤방식으로 처리할것인지, 또 어떠한 알고리즘을 통해서 정답에 접근할것인지에대한 많은 고민이 요구됬다.

특히 데이터를 잘못처리하면 오버플로우가 발생하거나 바로 시간초과가 떠버렸다.

따라서 앞으로의 단순 문법과 구현하는 법에대해서 공부하는것대신 여러 알고리즘과 자료구조에대해 공부해야겠다 다짐했다.

문제를 보고 수많은 알고리즘중에 문제에 알맞은 알고리즘을 코딩해야하는걸 생각하니..아직 갈길이 멀고 이제 겨우 한걸음 내딪은 느낌이지만 이제라도 한걸음을 걸었으니 걸음을 멈추지만 않는걸 목표로 할것이다.

그러다보면 목표와 가까워질 수 있을거 같다.

목표는 9월까지 골드5를 달성하는 것이다.

'백준' 카테고리의 다른 글

백준 2822번 "점수 계산"  (0) 2024.04.24
백준 1181번 "단어정렬"  (0) 2024.04.21
백준 1193번 "분수찾기"  (1) 2024.04.20
백준 1417번 "소트인사이드"  (0) 2024.04.16
백준 2018번 "수들의 합 5"  (0) 2024.04.15
백준 2822번
  • 문제
더보기

상근이는 퀴즈쇼의 PD이다. 이 퀴즈쇼의 참가자는 총 8개 문제를 푼다. 참가자는 각 문제를 풀고, 그 문제를 풀었을 때 얻는 점수는 문제를 풀기 시작한 시간부터 경과한 시간과 난이도로 결정한다. 문제를 풀지 못한 경우에는 0점을 받는다. 참가자의 총 점수는 가장 높은 점수 5개의 합이다. 

상근이는 잠시 여자친구와 전화 통화를 하느라 참가자의 점수를 계산하지 않고 있었다. 참가자의 8개 문제 점수가 주어졌을 때, 총 점수를 구하는 프로그램을 작성하시오.

  • 입력
더보기

8개 줄에 걸쳐서 각 문제에 대한 참가자의 점수가 주어진다. 점수는 0보다 크거나 같고, 150보다 작거나 같다. 모든 문제에 대한 점수는 서로 다르다. 입력으로 주어지는 순서대로 1번 문제, 2번 문제, ... 8번 문제이다.

 

  • 출력
더보기

첫째 줄에 참가자의 총점을 출력한다. 둘째 줄에는 어떤 문제가 최종 점수에 포함되는지를 공백으로 구분하여 출력한다. 출력은 문제 번호가 증가하는 순서이어야 한다.

예제 입출력

 

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

 

2822번: 점수 계산

8개 줄에 걸쳐서 각 문제에 대한 참가자의 점수가 주어진다. 점수는 0보다 크거나 같고, 150보다 작거나 같다. 모든 문제에 대한 점수는 서로 다르다. 입력으로 주어지는 순서대로 1번 문제, 2번 문

www.acmicpc.net

 

 

 

처음이자 정답으로 제출한 코드

 

const fs = require('fs');
const input = fs.readFileSync("/dev/stdin").toString().trim().split("\n").map(item=>item.replace('\r',""));

let num_list = [];
//입력받은 값을 문제번호와 점수값을 가지고 있는 obj로서 배열에 저장
for(let i = 0;i<input.length;i++){
    num_list.push(new Number(i+1,parseInt(input[i])))
}

//객체값중 점수에해당 하는 값을 정렬
num_list.sort(function (a,b){
    if (a.num > b.num) return -1;
    else if(a.num < b.num) return 1;
    else return 0;
})

//객체 생성 함수
function Number(idx,num){
    this.idx = idx;
    this.num = num;
}


let result = [];
let total = 0;
//최고 점수5개를 추린 후 총 점수를 구함
for(let i = 0; i<5;i++){
    result.push(num_list[i].idx);
    total += num_list[i].num;
}

//정답 출력
console.log(total);
console.log(result.sort().join(" "));

 

결과

 

 

위 문제를 고민하면서 가장큰 걸림돌은 문제의 번호를 기억할 변수가 필요했다는 것이다.

쉽게보면 점수를 내림차순으로 정렬한뒤 앞에서부터 5문제를 짜르면되는데

문제는 해당 문제가 몇번쨰인지 정렬을하면서 뒤섞인다는 점이다.

 

그래서 생각했던 것이 key:value 형태로서 저장해서 value로 정렬하고 출력할땐 key값으로 출력하는 형태를 생각했다.

그러다 구현이 쉬운 객체로 문제를 풀게되었다.

 

1. index번호 +1(=문제번호) 와 입력받은 점수를 통하여 객체로서 num_list 라는 배열에 저장한다.

2. num_list에 접근하여 점수를 기준으로 정렬하는 sort()를 작성한다.

3. 이후 정렬되어 있는 배열에서 0~4번째 인덱스를 다른 배열에 옮긴다.

4. 해당 배열을 정렬하여 문제번호가 오름차순으로 출력될수 있도록 한다.

 

문제를 공략한 방법은 위와 같다.  

key:value 형태로 데이터를 저장하는 법을 알고 그것을 value와 key를 기준으로 정렬하는 법을 안다면 쉽게 풀 수 있는 문제였던거 같다.

'백준' 카테고리의 다른 글

백준 sliver V 달성 후기  (1) 2024.04.24
백준 1181번 "단어정렬"  (0) 2024.04.21
백준 1193번 "분수찾기"  (1) 2024.04.20
백준 1417번 "소트인사이드"  (0) 2024.04.16
백준 2018번 "수들의 합 5"  (0) 2024.04.15
백준 1181번

 

  • 문제
더보기

알파벳 소문자로 이루어진 N개의 단어가 들어오면 아래와 같은 조건에 따라 정렬하는 프로그램을 작성하시오.

  1. 길이가 짧은 것부터
  2. 길이가 같으면 사전 순으로

단, 중복된 단어는 하나만 남기고 제거해야 한다.

 

  • 입력
더보기

첫째 줄에 단어의 개수 N이 주어진다. (1 ≤ N ≤ 20,000) 둘째 줄부터 N개의 줄에 걸쳐 알파벳 소문자로 이루어진 단어가 한 줄에 하나씩 주어진다. 주어지는 문자열의 길이는 50을 넘지 않는다.

 

  • 출력
더보기

조건에 따라 정렬하여 단어들을 출력한다.

 

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

 

1181번: 단어 정렬

첫째 줄에 단어의 개수 N이 주어진다. (1 ≤ N ≤ 20,000) 둘째 줄부터 N개의 줄에 걸쳐 알파벳 소문자로 이루어진 단어가 한 줄에 하나씩 주어진다. 주어지는 문자열의 길이는 50을 넘지 않는다.

www.acmicpc.net

 

 

 

 

처음 제출한 코드
const fs = require('fs');
const input = fs.readFileSync("/dev/stdin").toString().trim().split("\n");

let word_num = +input[0];
let words = [];
let result = [];

//입력받은 값을 배열화
for(let i = 1;i<input.length;i++){
    words.push(input[i].trim());
}

//선형 검색
for(let i = 0;i<words.length;i++){
    for(let j = i+1;j<words.length;j++){
    	//단어의 길이를 비교하여 서로 위치를 바꿔줌
        if(words[i].length > words[j].length){
            let buffer = words[i];
            words[i] = words[j];
            words[j] = buffer;
            i--;
            break;
        }
    }
}

//선형검색
for(let i = 0;i<words.length;i++){
    for(let j = i+1;j<words.length;j++){
    	//같은 단어일경우 배열에서 삭제
        if(words[i] == words[j]){
            words.splice(j,1);
            i--;
            break;    
        }
        //단어의 길이가 같을경우 서로의 위치를 바꿔줌
        if(words[i].length == words[j].length){
            let iString = [];
            let jString = [];
            iString = words[i].toString();
            jString = words[j].toString();
            if(iString[0] > jString[0]){
                let buffer = words[i];
                words[i] = words[j];
                words[j] = buffer;
                i--;
                break;
            }
        }
    }
}
//출력
for(let i = 0; i < words.length;i++){
    console.log(words[i]);
}

 

 

처음 위 문제를 봤을때 아무 계획없이 무작정 구현만 하면 되겠구나 싶었다.

그결과 위와 같은 깨끗하지 않은 코드가 탄생하게 되었다..

 

위에서 작성한것은 js에서 제공하는 메소드를 적절히 사용하지 못한거 같다.

딱히 이렇다할 풀이방법이 없고 그저 배열로 만들어 선형검색으로 전체 배열을 검색하고 확인하여 데이터를 처리했다.

 

그결과는 당연히 시간초과이다!

 

위와 같은 방법이 정답이 될 수도 있겠지만(0.000001% 정도) 

위 방식은 처리해야하되는 데이터가 늘어나면 늘어날 수록 처리해야하는 양이 기하급수적으로 늘어난다.

 

즉,효율성면에서 완전 꽝이라는 것이다...

 

 

 

정답으로 제출한 코드
const fs = require('fs');
const input = fs.readFileSync("/dev/stdin").toString().trim().split("\n");

let word_num = +input[0];
let words = [];
let words_length = [];

for(let i = 1;i<input.length;i++){
    words.push(input[i].trim());
    words_length.push(input[i].trim().length);
}

//단어의 길이가 가장 큰것을 기준으로 배열의 크기를 선언한다.
let result = new Array(Math.max(...words_length));
for(let i = 0; i < result.length;i++){
    result[i] = [];
}

//단어의 길이별로 배열에 push 해준다
for(let i = 0; i < words.length; i++){
    result[words[i].length-1].push(words[i]);
}


for(let i = 0; i < result.length; i++){
	//정렬
    result[i].sort();
    for(let j = 0; j < result[i].length; j++){
    	//중복되있는 단어는 배열에서 제거해준다
        if(result[i][j] == result[i][j+1]){
            result[i].splice(j,1);
            j--;
        }
    }
    //배열안에 있는 값을 차례대로 출력해준다
    for(let j = 0;j<result[i].length;j++){
        console.log(result[i][j]);
    }
}

 

결과

 

 

문제를 해결함에 있어서 가장 중요한 단서는 단어의 길이인거 같다.

 

그래서 입력받은 값들을 1차적으로 분류를 해주었다.

 

단어의 길이가 같은것끼리 한 배열안에 모이도록 분류를 했다.

 

그 이후 배열안에 있는것만 정렬하여 같은 단어를 제거해주는 단계를 거쳤다.

(현재 이 글을 작성하면서 중복단어의 제거는 set 를 사용했다면 더 간편하게 해결했을거 같다는 생각이 든다)

 

초기보다 훨씬 깔끔한 코드가 짜여진것같다.

역시 무작정 구현보다는 어떻게하면 효율적으로 코드를 짤 수 있을까 많은 생각을 해야할거 같다..

'백준' 카테고리의 다른 글

백준 sliver V 달성 후기  (1) 2024.04.24
백준 2822번 "점수 계산"  (0) 2024.04.24
백준 1193번 "분수찾기"  (1) 2024.04.20
백준 1417번 "소트인사이드"  (0) 2024.04.16
백준 2018번 "수들의 합 5"  (0) 2024.04.15
백준 1193번
  • 해당 문제는 예제를 활용하여 일련의 규칙을 찾고 그것을 구현한다면 크게 어렵지 않은 문제였다. 

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

 

1193번: 분수찾기

첫째 줄에 X(1 ≤ X ≤ 10,000,000)가 주어진다.

www.acmicpc.net

 

 

처음 제출한 코드
const fs = require('fs');
const input = fs.readFileSync("/dev/stdin").toString().trim();

let num = +input;

let addNum = 2;
let check = 1;

//입력받은 값이 어느부위에 해당하는지 확인
while(check < num){
    check += addNum;
    addNum++;
}

check -= addNum - 2;
let repeat = addNum;

//분수찾기
for(let i = 1; i < repeat; i++){
    let result = "";
    if(check == num){
        console.log(result + i + "/" + (addNum-1));
        break;
    }
    else{
        addNum--;
        check++;
    }
}

 

 

내가 찾은 해당 문제의 규칙은 대각선으로 보았을때 가운데를 기준으로 서로 대칭된다는점이다.

규칙을 찾을때 가장 좋은방법이 일단 해보는것이다.

 

1 - 1/1

 

2-1/2

3-2/1

 

4-3/1

5-2/2

6-1/3

 

7-1/4

8-2/3

9-3/3

10-4/1

 

11-5/1

...

15-5/1

 

 

나열하고 분류해보면 위와 같은 규칙이 보인다.

2와 3이 서로 대칭, 4와 6이 서로 대칭이다.

그리고 이를 한묶음으로 생각했을때 묶음안의 숫자의 개수가

1,2,3,4,5 로 늘어난다.

 

이와 같은 규칙을 발견했을때 생각해낸 방식이

 

1.입력받은 값이 어느 묶음에 해당하는지 알아낸다.

2.해당 묶음의 시작점부터 숫자를 늘려가며 분자는 ++ 분모는 -- 해나간다.

3.만일 입력값과 동일한 숫자가되면 해당 분자와 분모를 출력한다.

 

 

입력받은값이 어느 묶음에 해당하는지 알아내기 위해서 반복문을 적극 활용하였다.

우선 check라는 변수를 선언하여 1부터 찾도록 했고

묶음의 개수가 1씩 늘어가는것을 계산하기 위하여 addNum 이라는 변수를 만들어 반복문 시행시마다 ++을 해주고 check에 더해주었다.

그리고 check변수가 입력값을 넘어가면 반복문을 그만두게 하였다.

 

그리고 위에서 알아낸 범위로 결과 값을 쉽게 구할 수 있었다.

하지만 위 코드가 틀린이유는 문제를 꼼꼼히 읽지 않아서이다...

 

문제의 예제에서는 묶음의 개수가 짝수일때와 홀수일때가 서로 다르다.

즉, 홀수일때는 시작할때 분자가 더크고 짝수일때는 시작할때 분모가 더크다.

그 예시는 아래와 같다.

2- 1/2

3- 3/1

 

7-1/4

11-5/1

 

따라서 해당하는 범위를 다시 한번 확인해줄 필요가 있었다.

 

 

정답으로 제출한 코드

 

const fs = require('fs');
const input = fs.readFileSync("/dev/stdin").toString().trim();

let num = +input;

let addNum = 2;
let check = 1;

//입력받은 값이 어느부위에 해당하는지 확인
while(check < num){
    check += addNum;
    addNum++;
}


check -= addNum - 2;
let repeat = addNum;

//분수찾기
for(let i = 1; i < repeat; i++){
    let result = "";
    if(check == num){
    	//역순점검
        if((repeat-1)%2 != 0){
            console.log(result + (addNum-1) + "/" + i);
        }
        else{
            console.log(result + i + "/" + (addNum-1));
        }
        break;
    }
    else{
        addNum--;
        check++;
    }
}

결과

 

 

위코드에서 틀린부분은 if조건문을 통해 쉽게 구현할 수 있었다.

'백준' 카테고리의 다른 글

백준 2822번 "점수 계산"  (0) 2024.04.24
백준 1181번 "단어정렬"  (0) 2024.04.21
백준 1417번 "소트인사이드"  (0) 2024.04.16
백준 2018번 "수들의 합 5"  (0) 2024.04.15
백준 1384번 "메시지"  (1) 2024.04.14
백준 1417번
  • 해당 문제는 sort를 이용하여 내림차순 정렬만 할줄 안다면 쉽게 구현할 수 있는 문제였다

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

 

1427번: 소트인사이드

첫째 줄에 정렬하려고 하는 수 N이 주어진다. N은 1,000,000,000보다 작거나 같은 자연수이다.

www.acmicpc.net

 

 

처음이자 정답으로 제출한 코드
const fs = require('fs');
const input = fs.readFileSync("/dev/stdin").toString().trim();

//입력값을 배열로서 저장
let number = [...input];

//배열을 내림차순 정렬
number.sort(function(a,b){
    if(a>b) return -1;
    else if(b>a) return 1;
    else return 0;
});

//정렬한 배열을 하나의 문자열로 합체
let result = number.join("");

console.log(result);

결과

 

 

 

해당 문제는 어떻게 풀지 보다는 그저 구현부터 시작한 문제였다. 즉, 풀이방법보다는 "너 내림차순 정렬 할 수 있니" 라고 묻는듯한 문제였다. 해당 문제를 구현하는데는 어렵지 않았다.

 

1.입력값을 배열로 저장한다.(sort를 이용하기 위해)

2. sort를 이용하여 내림차순 정렬을 한다.

3. 정답을 위해 내림차순 정렬한 배열을 join을 이용하여 하나의 문자열로 만들어준다.

4.제출

 

이게 전부인 문제였던거 같다.

'백준' 카테고리의 다른 글

백준 1181번 "단어정렬"  (0) 2024.04.21
백준 1193번 "분수찾기"  (1) 2024.04.20
백준 2018번 "수들의 합 5"  (0) 2024.04.15
백준 1384번 "메시지"  (1) 2024.04.14
백준 1316번 "그룹 단체 체커"  (0) 2024.04.13
백준 2018번
  • 해당 문제는 연속하는 숫자들의 합이라는 점에서 풀기 수월했던 문제이다.

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

 

2018번: 수들의 합 5

어떠한 자연수 N은, 몇 개의 연속된 자연수의 합으로 나타낼 수 있다. 당신은 어떤 자연수 N(1 ≤ N ≤ 10,000,000)에 대해서, 이 N을 몇 개의 연속된 자연수의 합으로 나타내는 가지수를 알고 싶어한

www.acmicpc.net

 

 

처음이자 정답으로 제출한 코드
const fs = require('fs');
const input = fs.readFileSync("/dev/stdin").toString().trim();

//항상 자기자신으로 표현이 가능하므로 최소치 = 1
let result = 1;
let number = +input;

//입력받은 숫자의 반만큼만 반복
for(let i = 1; i <number/2;i++){
    let check = i;
    let num_plus = i+1;
    
    //연속하는 숫자의 합을 더해보다가 입력받은 숫자보다 높아지면 중지
    while(check < number){
        check += num_plus;
        num_plus++;
    }

	//연속한 숫자를 더한값이 입력값과 같으면 결과값 +1
    if(check==number){
        result++;
    }
}

console.log(result);

 

결과

 

 

 

이 문제를 보고 생각한 풀이법은 다음과 같다.

 

1. 연속하는 숫자의 반만큼 반복하는 반복문을 만든다.

    (반이상의 연속하는 숫자를 더하면 무조건 입력받은 값을 넘기때문)

 

2. 1부터 시작하여 연속하는 숫자들의 합을 구해본다.

 

1부터 시작하여

1 + 1 = 2

2 + 2 = 4

3 + 3 = 6

6 + 4 = 10

...

 

이를 반복하다 입력받은 값보다 커지면 반복을 멈춘다.

 

 

3. 위 반복문에서 나온값이 입력값과 같으면 결과값에 + 1 을 해준다.

 

 

위 문제는 반복문을 잘다루는것이 핵심이었던거 같다. 왜냐하면 계속 1씩 증가하는 변수와 그 값을 더해서 입력값과 비교할 값 이 두가지 값을 한 반복문안에서 적절히 사용해야하기 때문이다. 어떻게 풀지 생각해낸 이후로 생각보다 쉽게 구현하여 풀 수 있었던 문제였다.

'백준' 카테고리의 다른 글

백준 1193번 "분수찾기"  (1) 2024.04.20
백준 1417번 "소트인사이드"  (0) 2024.04.16
백준 1384번 "메시지"  (1) 2024.04.14
백준 1316번 "그룹 단체 체커"  (0) 2024.04.13
백준 1475번 "방번호"  (0) 2024.04.12
백준 1384번
  • 위 문제는 처음에 문제 이해를 잘못해서 풀이방향이 잘못될뻔한 문제이다..종이를 넘기는것이 입력받은 값기준 첫번째 줄이 두번째줄에게 종이를 넘기는 것이므로 예제 1번에서 N은 아래로 두번째 있는 아이가 쓴것이라고 이해했다.근데 왜인지 위로 두번째를 넘겼어야했다. 이건 아직도 잘모르겠지만..위로 하니까 풀렸다(예제출력을 보고 알았다)

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

 

1384번: 메시지

그룹 번호를 "Group 1"과 같이 출력함으로써 출력을 시작합니다. 그 다음 줄부터 누가(A) 누구(B)에게 나쁜 말을 했는지 "A was nasty about B"로 한 줄씩 출력합니다. 나쁜 말이 여러 개라면, 입력받은 순

www.acmicpc.net

 

 

처음이자 정답으로 제출한 코드
const fs = require('fs');
const input = fs.readFileSync("/dev/stdin").toString().trim().split("\n");

//그룹과 종이에 적힌값을 입력받아 함수로서 처리
//child 배열을 검색 만일 N이 존재할경우 badChild를 true로 변경하고 해당하는 인덱스를 위로 j칸 찾는다.
//이때 i-j가 음수일 수 있으므로 이를 확인하여 해당경우는 반대로 연산
const checkPN = (group,child) => {
    console.log("Group " + group);
    let badChild = false;
    for(let i = 0;i<child.length;i++){
        for(let j = 1; j < child[0].length;j++){
            if(child[i][j] == "N"){
                badChild = true;
                if((i - j) < 0){
                    console.log(child[(i-j) + child.length][0] + " was nasty about " + child[i][0]);
                }
                else{
                    console.log(child[i-j][0] + " was nasty about " + child[i][0]);
                }
            }
        }
    }
    if(!badChild){
        console.log("Nobody was nasty");
    }
    console.log();
}

let roof = 0;
let group = 1;

//입력값을 그룹인원만큼 뽑아내어 함수에게 매개변수로 주며 호출
while(Number(input[roof]) != 0){
    let childPaper = [];
    for(let i = roof + 1; i <= roof + Number(input[roof]);i++){
        childPaper.push(input[i].trim().split(' '));
    }
    checkPN(group,childPaper);
    
    roof += Number(input[roof])+1;
    group++;
}

 

결과

 

 

첫번째 제출에서 출력형식이 잘못됬던 점은 그룹의 인원을 출력하고 console.log()로 띄어쓰기를 한번 해주어야됬었다.

 

위 문제를 보고 떠올린 아이디어는 간단하다.

이중배열로 데이터를 받고 각 인덱스의 0번째 인덱스에는 아이들의 이름이 들어갈것이고 그 이후의 인덱스에는 P 또는 N의 값이 있을것이다.

 

이중배열로 1번째 배열부터 검색하여 N 이라는 값이 나올경우에는 badChild이라는 boolean 값을 참으로 바꾸고 N이 나온 인덱스로부터 역추적하면된다.

역추적은 상하인덱스로 이동을 해주면되기 떄문에 위 코드에서는 j번째 인덱스는 놔두고 i번째 인덱스를 옮겨주면된다.

 

그 이후 추적한 i번째 인덱스의 [0]번째 값에는 이름이 들어있으므로 이와 기존 i번째 인덱스의 [0] 번째 값을 출력해주면된다.

 

만일 nasty 학생이 없을경우  badChild 값이 false로 유지되므로 if 문을 통해 !badChild 일경우 nasty 한 학생이 없었음을 출력해주면된다.

 

위 문제는 단순 구현의 문제로 구현하는데는 오래걸렸지만 아이디어를 내는 부분에서는 크게 생각할거리가 없었던거 같다.

'백준' 카테고리의 다른 글

백준 1417번 "소트인사이드"  (0) 2024.04.16
백준 2018번 "수들의 합 5"  (0) 2024.04.15
백준 1316번 "그룹 단체 체커"  (0) 2024.04.13
백준 1475번 "방번호"  (0) 2024.04.12
백준 2563번 "색종이"  (0) 2024.04.12

 

백준 1316번
  • 이 문제는 문자열을 배열화 하는 법에대해 공부할 수 있었던 문제였다. 그리고 이중배열을 다루는데 좀더 능숙해질 수 있었다.

 

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

 

1316번: 그룹 단어 체커

그룹 단어란 단어에 존재하는 모든 문자에 대해서, 각 문자가 연속해서 나타나는 경우만을 말한다. 예를 들면, ccazzzzbb는 c, a, z, b가 모두 연속해서 나타나고, kin도 k, i, n이 연속해서 나타나기 때

www.acmicpc.net

 

 

 

처음이자 정답으로 제출한 코드
const fs = require('fs');
const input = fs.readFileSync("/dev/stdin").toString().trim().split("\n");

//입력받은값들을 배열로서 저장
let words = [];
for(let i = 0; i < input.length; i++){
    words.push(input[i].trim());
}

let result = 0;


for(let i = 1; i < words.length; i++){
	//받은 문자를 배열화
    let check = [...words[i]];
    let linked = true;
    
    //이중배열을 통해 이어서 같은 알파벳이 나오면 same true 유지
    //다른 알파벳이 나오면 false로 전환
    //이후 다시 같은 알파벳이 나오면 linked를 false로 변경하여 링크단어가 아님을 표시
    for(let j = 0; j < check.length;j++){
        let same = true;
        for(let k = j+1; k < check.length; k++){
            if(check[j] != check[k]){
                same = false;
            }
            if(!same){
                if(check[j] == check[k]){
                    linked = false;
                }
            }
        }
    }
    if(linked){
        result++;
    }
}

console.log(result);

결과

 

이 문제를 처음 봤을떄 문자를 배열화하여 이중배열로 확인하면 금방 풀리겠다 라고 생각했다.

 

처음의 생각했던 방식은 아래와 같다.

 

happy 라는 입력값이 있을경우 이를 배열화 하여

[ 'h', 'a', 'p', 'p', 'y'] 로 변환하고 이중배열을 통하여 이어지는 알파벳들을 검사한다.

 

i번째 인덱스가 h일때 j번째 인덱스는 appy를 검사하고

i번째 인덱스가 a일때 j번째 인덱스는 ppy를 검사한다.

 

이때 same 이라는 boolean 값을 하나 만들어 반복문이 실행될때 이 값을 true로 두고 

i번째 인덱스값과 j번째 인덱스가 달라질경우 해당 값을 false로 변경한다.

 

이떄 same값이 false 일때부터 i번째 인덱스와 j번째 인덱스가 같을경우 linked 값을 false로 변경하여 링크단어가 아님을 표시한다.

 

마지막으로 반복문이 끝날때 linked 값이 true이면 result 값에 1을 더하고 아닐경우 그냥 패스한다.

 

 

해당 문제를 위와 같은 과정으로 풀이하였고 다행히 한번에 통과할 수 있었다.

'백준' 카테고리의 다른 글

백준 2018번 "수들의 합 5"  (0) 2024.04.15
백준 1384번 "메시지"  (1) 2024.04.14
백준 1475번 "방번호"  (0) 2024.04.12
백준 2563번 "색종이"  (0) 2024.04.12
백준 1312번 "소수"  (0) 2024.04.11

+ Recent posts