반응형

문제

4 × 3 = 12이다.

이 식을 통해 다음과 같은 사실을 알 수 있다.

3은 12의 약수이고, 12는 3의 배수이다.

4도 12의 약수이고, 12는 4의 배수이다.

두 수가 주어졌을 때, 다음 3가지 중 어떤 관계인지 구하는 프로그램을 작성하시오.

  1. 첫 번째 숫자가 두 번째 숫자의 약수이다.
  2. 첫 번째 숫자가 두 번째 숫자의 배수이다.
  3. 첫 번째 숫자가 두 번째 숫자의 약수와 배수 모두 아니다.

입력

입력은 여러 테스트 케이스로 이루어져 있다. 각 테스트 케이스는 10,000이 넘지않는 두 자연수로 이루어져 있다. 마지막 줄에는 0이 2개 주어진다. 두 수가 같은 경우는 없다.

출력

각 테스트 케이스마다 첫 번째 숫자가 두 번째 숫자의 약수라면 factor를, 배수라면 multiple을, 둘 다 아니라면 neither를 출력한다.

반응형

해설

isFactor 함수와 isMultiple 함수 두가지만 만들면 쉽게 풀 수 있다.

쉬운 문제인 만큼 해설만 있으면 충분할듯

코드

// const dataFile = './data';
const dataFile = '/dev/stdin';
const fs = require('fs');
const inputs = fs.readFileSync(dataFile).toString().split('\n').map(el => el.split(" ").map(el => parseInt(el)));

const run = (inputs) => {
  let i = 0;
  while(true) {
    const input = inputs[i]
    if(isLast(input)) { break; } 
    if(isFactor(input)) {
      console.log("factor")
    } else if (isMultiple(input)) {
      console.log("multiple")
    } else {
      console.log("neither")
    }
    i++;
  }
}

const isLast = (input) => {
  return input[0] == 0 && input[1] == 0;
}

const isFactor = (input) => {
  if(input[0] >= input[1]) {
    return false;
  }

  return input[1]%input[0] == 0
}

const isMultiple = (input) => {
  if(input[1] >= input[0]) {
    return false;
  }

  return input[0]%input[1] == 0
}
run(inputs);
반응형
반응형

Mysql을 통해 환경을 세팅하는 중 가장 흔하게 만날 수 있는 오류가 하나 있다.

 

아래와 같은 오류인데, 이 오류가 무엇인지! 해결방법은 무엇인지 알아보자.

 

Client does not support authentication protocol requested by server; consider upgrading MySQL client

오류의 원인

Mtysql 8부터는 Pluggable Authentication methods를 지원한다. 기본적으로 Caching_sha2_password가 사용이 되고,

우리가 흔히 사용하는 user/password 방법인 mysql_native_password를 사용하는 방법은 default가 아니다.

당연히 SHA2와 같은 암호화 알고리즘을 쓰는 방법은 단순히 Password를 사용하는 방법보다 안전하다.

하지만 Mysqljs에서는 mysql_native_password만 지원을 하기 때문에 위와 같은 문제가 발생한다.

mysqljs를 꼭!! 반드시!! 사용해야한다면 아래 1번 해결방법을 따라하면 된다.

 

반응형

해결방법

해결방법1

특정 사용자에 대해서 mysql_native_password 접근을 허용하면 된다.

아래 SQL문으로 접근을 허용 할 수 있다.

ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password '비밀번호'

매우 간단하고 효과적인 방법이다. 그리고 Mysqljs에 의존적인 라이브러리를 사용하고 있는 경우 어쩔 수 없이 선택해야 하는 방법이기도 하다. 하지만 이 방법을 사용할때 한가지는 알고있으면 좋을 것 같다.

"더 Secure한 방법이 있지만, 나는 지금 그 이점을 버리고 내가 편한 방법으로 진행중이다"

 

해결방법2

오래된 Mysqljs를 버리고 다른 Library로 교체

https://www.npmjs.com/package/mysql2

 

mysql2

fast mysql driver. Implements core protocol, prepared statements, ssl and compression in native JS. Latest version: 2.3.3, last published: a year ago. Start using mysql2 in your project by running `npm i mysql2`. There are 3243 other projects in the npm re

www.npmjs.com

https://dev.mysql.com/doc/dev/connector-nodejs/8.0/

 

MySQL Connector/Node.js X DevAPI Reference Index

MySQL Connector/Node.js MySQL Connector/Node.js is a MySQL 8 driver for Node.js, officially supported and maintained by Oracle. It contains a pure JavaScript implementation of the X DevAPI, an Application Programming Interface for working with the MySQL Do

dev.mysql.com

 

mysql2의 경우 mysql js를 fork하여 발전시킨 오픈소스 라이브러리이고,

connector-nodejs는 Oracle에서 개발, 유지중인 nodejs mysql driver이다.

 

 

반응형
반응형

정렬 알고리즘 중 삽입 정렬(Insertion sort)에 대해서 설명을 드리고, 백준 알고리즘에서 실전 문제를 푸는 것 까지 진행을 해볼게요.

 

삽입 정렬은 정렬 알고리즘을 처음 접하시는 분들도 매우 직관적으로 이해 할 수 있는 알고리즘 입니다.

 

매우 간단한 알고리즘인데요.

 

간단하게 설명을 드리면

삽입 정렬은 배열의 모든 요소를 하나씩 비교하면서,
비어있는 배열에 하나씩 옮기는 방식의 알고리즘 입니다.
이 옮기는 과정에서 정렬이 되도록 삽입 해줍니다.

즉, 올바른 위치에 계속해서 삽입(Insertion) 만 해준다면 우리는 정렬이 된 배열을 얻을 수 있습니다.

 

그림으로 설명해 드릴게요.

 

저희는 3, 1, 7 3개의 숫자가 있는 배열을 가지고 있고,

이 배열을 정렬을 하고 싶습니다.

오름차순으로 정렬을 하여 1, 3, 7 배열을 얻고 싶은거죠.

 

위에 설명대로 첫번째 3을 비어있는 배열에 옮기겠습니다.

 

첫번째 요소이고 옮길 곳은 배열이 비어있기 때문에 그냥 3을 옮겨놓습니다.

 

다음으로 1을 옮겨야 하는데요.

 

이미 3보다 큰 3이 배열에 들어가 있기 때문에

1은 3보다 앞에 삽입(Insertion) 되어야 합니다.

 

3을 한칸 뒤로 밀고 1을 넣으면 아래처럼 됩니다.

 

마지막으로 7을 넣어야 하는데,

복사본 배열과 비교를 해보니 모든 숫자가 7보다 작네요.

그럼 제일 끝에 삽입을 하면 되겠네요.

 

이렇게 정렬이 완료 되었습니다.

 

백준에서 관련 문제를 찾아보겠습니다.

 

많은 정렬 문제가 있지만, 삽입 정렬은 O(n^2)의 방법이기 때문에 시간제약이 적은 문제를 가서 풀어야합니다.

 

백준에서는 2750번: 수 정렬하기 문제에서 연습해보실 수 있습니다.

 

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

 

2750번: 수 정렬하기

첫째 줄에 수의 개수 N(1 ≤ N ≤ 1,000)이 주어진다. 둘째 줄부터 N개의 줄에는 수 주어진다. 이 수는 절댓값이 1,000보다 작거나 같은 정수이다. 수는 중복되지 않는다.

www.acmicpc.net

 

해설

저는 문제를 풀기에 앞서서 함수를 먼저 작성하였는데요.

 

정렬을 위한 Sort라는 함수를 작성하였고.

 

삽입정렬에서의 삽입 이라는 기능을 위한 insert라는 함수를 정의하였습니다.

 

Sort 함수에서는 기존 배열의 요소들을 하나씩 insert 함수를 사용하여 정렬을 하고,

 

insert 함수는 각 요소가 들어갈 위치를 찾고 삽입하는 역할을 수행합니다.

 

코드

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
const fs = require('fs');
const input = fs.readFileSync('/dev/stdin').toString().split('\n');
const N = parseInt(input[0]);
 
const list = [];
for(let i = 1; i <= N; i++) {
  list.push(parseInt(input[i]));
}
 
// sort 함수 구현
function sort(unsortedList) {
  const sortedList = []
  for(let num of unsortedList) {
    insert(sortedList, num)
  }
  return sortedList;
}
 
// 삽입 함수 구현
function insert(sortedList, num) {
  let index = -1;
  for(let i = 0; i < sortedList.length; i++) {
    if(sortedList[i] < num) {
      continue;
    } else {
      index = i;
      break;
    }
  }
 
  if(index < 0) {
    sortedList.push(num);
  } else {
    sortedList = sortedList.splice(index, 0, num);
  }
}
 
let sortedList = sort(list);
 
for(let num of sortedList) {
  console.log(num);
}
cs
반응형
반응형

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

 

1436번: 영화감독 숌

666은 종말을 나타내는 숫자라고 한다. 따라서, 많은 블록버스터 영화에서는 666이 들어간 제목을 많이 사용한다. 영화감독 숌은 세상의 종말 이라는 시리즈 영화의 감독이다. 조지 루카스는 스타

www.acmicpc.net

문제

666은 종말을 나타내는 숫자라고 한다. 따라서, 많은 블록버스터 영화에서는 666이 들어간 제목을 많이 사용한다. 영화감독 숌은 세상의 종말 이라는 시리즈 영화의 감독이다. 조지 루카스는 스타워즈를 만들 때, 스타워즈 1, 스타워즈 2, 스타워즈 3, 스타워즈 4, 스타워즈 5, 스타워즈 6과 같이 이름을 지었고, 피터 잭슨은 반지의 제왕을 만들 때, 반지의 제왕 1, 반지의 제왕 2, 반지의 제왕 3과 같이 영화 제목을 지었다.

하지만 숌은 자신이 조지 루카스와 피터 잭슨을 뛰어넘는다는 것을 보여주기 위해서 영화 제목을 좀 다르게 만들기로 했다.

종말의 숫자란 어떤 수에 6이 적어도 3개이상 연속으로 들어가는 수를 말한다. 제일 작은 종말의 숫자는 666이고, 그 다음으로 큰 수는 1666, 2666, 3666, .... 과 같다.

따라서, 숌은 첫 번째 영화의 제목은 세상의 종말 666, 두 번째 영화의 제목은 세상의 종말 1666 이렇게 이름을 지을 것이다. 일반화해서 생각하면, N번째 영화의 제목은 세상의 종말 (N번째로 작은 종말의 숫자) 와 같다.

숌이 만든 N번째 영화의 제목에 들어간 숫자를 출력하는 프로그램을 작성하시오. 숌은 이 시리즈를 항상 차례대로 만들고, 다른 영화는 만들지 않는다.

입력

첫째 줄에 숫자 N이 주어진다. N은 10,000보다 작거나 같은 자연수이다.

출력

첫째 줄에 N번째 영화의 제목에 들어간 수를 출력한다.

 

해설

브루트포스 문제이기 때문에 "1부터 쭉 진행하며 N번째 숫자를 찾으면 된다" 라는 접근으로 문제를 해결하였다.

 

첫번째로 작성한 코드는 isEndNumber라는 함수로 input 숫자가 종말의 숫자인지(666을 포함하는 숫자인지) boolean의 output을 내는 참수를 작성하였다.

 

해당 함수는 숫자를 스트링으로 변환 후 6이 연속 3번 나오면 true를 반환하도록 하였다.

 

이후 1부터 진행하며 N번대 EndNumber를 찾아 stdout으로 출력하면 끝난다.

 

코드

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
const fs = require('fs');
const input = fs.readFileSync('/dev/stdin').toString()
const n = parseInt(input);
 
function isEndNumber(num) {
  const str = String(num);
  let count = 0;
  for(let i = 0; i < str.length; i++) {
    const char = str[i];
    if(char === '6') {
      count++;
    } else {
      count = 0;
    }
 
    if(count >= 3) {
      return true;
    }
  }
 
  return false;
}
 
let currentNum = 1;
let count = 0;
while(true) {
  if(isEndNumber(currentNum)) {
    count++;
    if(count === n) {
      console.log(currentNum);
      break;
    }
  }
  currentNum++;
}
cs
반응형
반응형

로컬에서 tsc 빌드는 정상적으로 되는데,

 

배포시 원격 서버에서 빌드를 할때 문제가 발생하였다.

(지금까지 빌드부터 배포까지 잘 되고 있었는데... 갑자기 발생하였다 ㅠㅠ)

 

정확히 어떤 환경 때문에 발생하게 되었는지는 파악하지 못했지만, tsconfig를 수정하여 문제를 해결 할 수 있었다.

 

오류 내용은 다음과 같다.

 

Property 'asyncIterator' does not exist on type 'SymbolConstructor'.

Cannot find name 'AsyncIterableIterator'. Do you need to change your target library? Try changing the `lib` compiler option to 'es2018' or later.

 

해결 방법은 tsconfig.json 파일에 해당 내용을 추가해주었다.

 

"compilerOptions": {

  "lib": [

    "esnext.asynciterable"

  ]

}

 

기존에 있던 lib에서 "esnext.asynciterable"를 추가하였고,

정상적으로 빌드, 배포 되었다.

반응형
반응형

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

 

1018번: 체스판 다시 칠하기

첫째 줄에 N과 M이 주어진다. N과 M은 8보다 크거나 같고, 50보다 작거나 같은 자연수이다. 둘째 줄부터 N개의 줄에는 보드의 각 행의 상태가 주어진다. B는 검은색이며, W는 흰색이다.

www.acmicpc.net

문제

지민이는 자신의 저택에서 MN개의 단위 정사각형으로 나누어져 있는 M*N 크기의 보드를 찾았다. 어떤 정사각형은 검은색으로 칠해져 있고, 나머지는 흰색으로 칠해져 있다. 지민이는 이 보드를 잘라서 8*8 크기의 체스판으로 만들려고 한다.

체스판은 검은색과 흰색이 번갈아서 칠해져 있어야 한다. 구체적으로, 각 칸이 검은색과 흰색 중 하나로 색칠되어 있고, 변을 공유하는 두 개의 사각형은 다른 색으로 칠해져 있어야 한다. 따라서 이 정의를 따르면 체스판을 색칠하는 경우는 두 가지뿐이다. 하나는 맨 왼쪽 위 칸이 흰색인 경우, 하나는 검은색인 경우이다.

보드가 체스판처럼 칠해져 있다는 보장이 없어서, 지민이는 8*8 크기의 체스판으로 잘라낸 후에 몇 개의 정사각형을 다시 칠해야겠다고 생각했다. 당연히 8*8 크기는 아무데서나 골라도 된다. 지민이가 다시 칠해야 하는 정사각형의 최소 개수를 구하는 프로그램을 작성하시오.

입력

첫째 줄에 N과 M이 주어진다. N과 M은 8보다 크거나 같고, 50보다 작거나 같은 자연수이다. 둘째 줄부터 N개의 줄에는 보드의 각 행의 상태가 주어진다. B는 검은색이며, W는 흰색이다.

출력

첫째 줄에 지민이가 다시 칠해야 하는 정사각형 개수의 최솟값을 출력한다.

 

해설

사실 부르트포스에 해설이랄게 뭐 있을까요? ㅠㅠ

하나하나 다 숫자를 세보면 됩니다!

 

저 같은 경우에는 첫번째 칸이 'B' 또는 'W'로 시작하고, 8x8 크기의 체스판을 칠할때

몇번을 칠하면 원하는 색으로 시작하는 체스판이 완성이 되는지

count하는 함수를 작성했어요.

 

countNeedPating(startRowNum, startColNum, startColor) 함수를 작성했고,

인수로 시작하는 row, col, color을 받아서 8x8을 직접 칠해보면서, count를 해줬습니다.

 

여기서 한가지 집중했던 점은

 

8x8 체스판은 64번을 칠하면 완성이 되는데,

첫번째 칸이 'B'일때와 'W'일때의 색칠해야 하는 횟수를 합치면 64가 된다는 것입니다.

따라서 B나 W로 시작하는 경우의 색칠 횟수 한번만 구하면 나머지 경우도 계산이 됩니다.

 

코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
const fs = require('fs');
const input = fs.readFileSync('/dev/stdin').toString().split('\n');
 
// input을 미리 정리합니다.
const [height, width] = input[0].split(' ').map(el => parseInt(el))
const originBoard = []
for(let i = 1; i <= height; i++) {
  let row = input[i].split('')
  originBoard.push(row)
}
 
// 우리가 색칠 할 Size를 먼저 정의를 해주었습니다.
// 문제를 풀때 x, y 만 수정하면 작은 경우의 수부터 테스트를 진행 할 수 있거든요.
const SIZE = {x:8, y:8}
 
// 색칠 횟수를 count 하는 함수를 먼저 정의합니다.
// 시작하는 위치에서 부터 SIZE에서 정의한 만큼의 체스판을 색칠해봅니다.
function countNeedPainting(startRowNum, startColNum, startColor) {
  let nextColor = startColor;
  let count = 0;
  // i = row
  for(let i = startRowNum; i < startRowNum + SIZE.x; i++) {
    // j = column
    for(let j = startColNum; j < startColNum + SIZE.y; j++) {
      if(originBoard[i][j] !== nextColor) {
        count++;
      }
      nextColor = nextColor === 'B' ? 'W' : 'B'
    }
    nextColor = nextColor === 'B' ? 'W' : 'B'
  }
  return count;
}
 
// 최소값을 미리 넉넉하게 설정해 뒀습니다.
let min = SIZE.x * SIZE.y;
// 전체 크기에서 체스판을 자를 수 있는 모든 경우의 수를 loop를 돌며 확인합니다.
for(let i = 0 ; i <= height - SIZE.x; i++) {
  for(let j = 0; j <= width - SIZE.y; j++) {
    const blakCount = countNeedPainting(i, j, 'B');
    const whiteCount = (SIZE.x * SIZE.y) - blakCount;
    const currentMin = blakCount > whiteCount ? whiteCount : blakCount
 
    if(min > currentMin) {
      min = currentMin
    }
  }
}
 
console.log(min)
cs
반응형
반응형

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

 

7568번: 덩치

우리는 사람의 덩치를 키와 몸무게, 이 두 개의 값으로 표현하여 그 등수를 매겨보려고 한다. 어떤 사람의 몸무게가 x kg이고 키가 y cm라면 이 사람의 덩치는 (x, y)로 표시된다. 두 사람 A 와 B의 덩

www.acmicpc.net

문제

우리는 사람의 덩치를 키와 몸무게, 이 두 개의 값으로 표현하여 그 등수를 매겨보려고 한다. 어떤 사람의 몸무게가 x kg이고 키가 y cm라면 이 사람의 덩치는 (x, y)로 표시된다. 두 사람 A 와 B의 덩치가 각각 (x, y), (p, q)라고 할 때 x > p 그리고 y > q 이라면 우리는 A의 덩치가 B의 덩치보다 "더 크다"고 말한다. 예를 들어 어떤 A, B 두 사람의 덩치가 각각 (56, 177), (45, 165) 라고 한다면 A의 덩치가 B보다 큰 셈이 된다. 그런데 서로 다른 덩치끼리 크기를 정할 수 없는 경우도 있다. 예를 들어 두 사람 C와 D의 덩치가 각각 (45, 181), (55, 173)이라면 몸무게는 D가 C보다 더 무겁고, 키는 C가 더 크므로, "덩치"로만 볼 때 C와 D는 누구도 상대방보다 더 크다고 말할 수 없다.

N명의 집단에서 각 사람의 덩치 등수는 자신보다 더 "큰 덩치"의 사람의 수로 정해진다. 만일 자신보다 더 큰 덩치의 사람이 k명이라면 그 사람의 덩치 등수는 k+1이 된다. 이렇게 등수를 결정하면 같은 덩치 등수를 가진 사람은 여러 명도 가능하다. 아래는 5명으로 이루어진 집단에서 각 사람의 덩치와 그 등수가 표시된 표이다.

이름(몸무게, 키)덩치 등수

A (55, 185) 2
B (58, 183) 2
C (88, 186) 1
D (60, 175) 2
E (46, 155) 5

위 표에서 C보다 더 큰 덩치의 사람이 없으므로 C는 1등이 된다. 그리고 A, B, D 각각의 덩치보다 큰 사람은 C뿐이므로 이들은 모두 2등이 된다. 그리고 E보다 큰 덩치는 A, B, C, D 이렇게 4명이므로 E의 덩치는 5등이 된다. 위 경우에 3등과 4등은 존재하지 않는다. 여러분은 학생 N명의 몸무게와 키가 담긴 입력을 읽어서 각 사람의 덩치 등수를 계산하여 출력해야 한다.

입력

첫 줄에는 전체 사람의 수 N이 주어진다. 그리고 이어지는 N개의 줄에는 각 사람의 몸무게와 키를 나타내는 양의 정수 x와 y가 하나의 공백을 두고 각각 나타난다.

출력

여러분은 입력에 나열된 사람의 덩치 등수를 구해서 그 순서대로 첫 줄에 출력해야 한다. 단, 각 덩치 등수는 공백문자로 분리되어야 한다.

 

해설

등수를 구하는 문제이기 때문에 정렬을 하고, 확실하지 않은 경우는 rank를 공동으로 부여하면 된다.

 

하지만 위 같은 방법으로 구현을 할 시에 귀찮다....

 

정렬(nLogn) + rank(n) 으로 구현이 가능하지만 n^2인 방법으로 문제를 풀었다.

 

문제를 푼 접근 방법은

 

"Rank는 결국 나보다 더치가 큰 사람의 숫자 + 1" 이다.

 

나보다 큰 사람이 없으면 rank가 1이 되고, 나보다 큰 사람이 9명이면 내 rank는 10이 된다.

 

다음 코드는 node를 이용하여 구현한 결과이다.

 

코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
const fs = require('fs');
const input = fs.readFileSync('/dev/stdin').toString().split('\n');
const num = parseInt(input[0]);
 
// Person class를 통해 문제를 풀어보겠습니다.
class Person {
  constructor(weight, height) {
    this.weight = weight;
    this.height = height;
    this.rank = 0;
  }
}
 
const people = []
 
// input 을 통해서 모든 사람의 정보를 people에 저장을 합니다.
for(let i = 1; i <= num; i++) {
  const [weight, height] = input[i].split(" ");
  const person = new Person(weight, height);
  people.push(person);
}
 
// 전체 사람 중에서 '나'보다 덩치가 큰 사람을 count 하고 +1을 하면 내 rank가 됩니다.
for(let i = 0; i < people.length; i++) {
  let currentPeople = people[i];
  const biggerPeople = people.filter(person => person.weight > currentPeople.weight && person.height > currentPeople.height);
  currentPeople.rank = biggerPeople.length + 1;
}
 
// 결과를 출력합니다.
for(let person of people) {
  console.log(person.rank);
}
cs
반응형
반응형

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

 

2231번: 분해합

어떤 자연수 N이 있을 때, 그 자연수 N의 분해합은 N과 N을 이루는 각 자리수의 합을 의미한다. 어떤 자연수 M의 분해합이 N인 경우, M을 N의 생성자라 한다. 예를 들어, 245의 분해합은 256(=245+2+4+5)이

www.acmicpc.net

문제

어떤 자연수 N이 있을 때, 그 자연수 N의 분해합은 N과 N을 이루는 각 자리수의 합을 의미한다. 어떤 자연수 M의 분해합이 N인 경우, M을 N의 생성자라 한다. 예를 들어, 245의 분해합은 256(=245+2+4+5)이 된다. 따라서 245는 256의 생성자가 된다. 물론, 어떤 자연수의 경우에는 생성자가 없을 수도 있다. 반대로, 생성자가 여러 개인 자연수도 있을 수 있다.

자연수 N이 주어졌을 때, N의 가장 작은 생성자를 구해내는 프로그램을 작성하시오.

입력

첫째 줄에 자연수 N(1 ≤ N ≤ 1,000,000)이 주어진다.

출력

첫째 줄에 답을 출력한다. 생성자가 없는 경우에는 0을 출력한다.

 

해설

문제에서 얻을 수 있는 힌트를 먼저 살펴보면

 

"가장 작은 생성자"

"없을 수도 있다"

 

두가지 정도를 찾을 수 있을것 같다.

 

분해합은 반드시 생성자보다 크기 때문에 0부터 시작하면서 하나씩 생성자가 될 수 있는지 확인을 하면서 진행하면 문제를 풀 수 있다.

 

0부터 시작하는 이유는 "가장 작은 생성자"를 찾는 문제이기 때문이다.

 

만약 "가장 큰 생성자"를 찾는 문제라면 N 부터 0까지 진행하면 된다.

 

쉬운 문제이기 때문에 설명은 코드 주석으로 적어 놓았다.

 

코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
const fs = require('fs');
const input = fs.readFileSync('/dev/stdin').toString();
 
const N = parseInt(input)
 
let M = 0
for(let i = 0; i < N; i++) {
  //각 자리수와 후보값의 합을 구하기 위한 변수
  let sum = 0;
 
  // 0부터 시작하는 후보값
  const candidateValue = i;
 
  //각 자리수를 구하기 위해서 숫자를 string으로 변환하여 계산한다.
  const stringValue = candidateValue.toString()
 
  for(let j = 0; j < stringValue.length; j++) {
    sum += parseInt(stringValue[j])
  }
 
  sum += candidateValue;
 
  if(sum == N) {
    M = candidateValue
    break;
  }
}
 
console.log(M)
cs
반응형
반응형

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

 

2798번: 블랙잭

첫째 줄에 카드의 개수 N(3 ≤ N ≤ 100)과 M(10 ≤ M ≤ 300,000)이 주어진다. 둘째 줄에는 카드에 쓰여 있는 수가 주어지며, 이 값은 100,000을 넘지 않는 양의 정수이다. 합이 M을 넘지 않는 카드 3장

www.acmicpc.net

문제

카지노에서 제일 인기 있는 게임 블랙잭의 규칙은 상당히 쉽다. 카드의 합이 21을 넘지 않는 한도 내에서, 카드의 합을 최대한 크게 만드는 게임이다. 블랙잭은 카지노마다 다양한 규정이 있다.

한국 최고의 블랙잭 고수 김정인은 새로운 블랙잭 규칙을 만들어 상근, 창영이와 게임하려고 한다.

김정인 버전의 블랙잭에서 각 카드에는 양의 정수가 쓰여 있다. 그 다음, 딜러는 N장의 카드를 모두 숫자가 보이도록 바닥에 놓는다. 그런 후에 딜러는 숫자 M을 크게 외친다.

이제 플레이어는 제한된 시간 안에 N장의 카드 중에서 3장의 카드를 골라야 한다. 블랙잭 변형 게임이기 때문에, 플레이어가 고른 카드의 합은 M을 넘지 않으면서 M과 최대한 가깝게 만들어야 한다.

N장의 카드에 써져 있는 숫자가 주어졌을 때, M을 넘지 않으면서 M에 최대한 가까운 카드 3장의 합을 구해 출력하시오.

입력

첫째 줄에 카드의 개수 N(3 ≤ N ≤ 100)과 M(10 ≤ M ≤ 300,000)이 주어진다. 둘째 줄에는 카드에 쓰여 있는 수가 주어지며, 이 값은 100,000을 넘지 않는 양의 정수이다.

합이 M을 넘지 않는 카드 3장을 찾을 수 있는 경우만 입력으로 주어진다.

출력

첫째 줄에 M을 넘지 않으면서 M에 최대한 가까운 카드 3장의 합을 출력한다.

 

해설

브루트포스(Brute Force) 문제이다.

카드 세장을 뽑아야하기 때문에, 간단하게 3중 loop를 이용해서 문제를 풀수 있다.

다만 한가지 주의를 해야하는 점은, 

! 동일한 카드를 뽑을 수 없다

위 사항만 주의한다면 쉽게 문제를 풀 수 있다.

코드가 간단하기 때문에 자세한 설명은 코드 주석으로 달아놓았다.

 

코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
const fs = require('fs');
const inputs = fs.readFileSync('/dev/stdin').toString().split("\n")
 
const firstLine = inputs[0].split(" ")
const secondLine = inputs[1].split(" ").map(el => parseInt(el))
 
const N = parseInt(firstLine[0])
const M = parseInt(firstLine[1])
 
let max = 0
//3장의 카드를 골라야 하기 때문에 i, j, k 3개의 index를 써서 for loop을 돈다
for(let i = 0; i < N; i++) {
  for(let j = 0; j < N; j++) {
    for(let k = 0; k < N; k++) {
      // 동일한 카드를 선택 할 수는 없기 때문에 아래 조건의 경우 다음 loop로 넘어간다.
      if(i == j || i == k || j == k) {
        continue;
      }
 
      // 서로 다른 카드가 선택된 경우 M을 초과하지 않는 최대값인지 확인 후 저장한다.
      const sum = secondLine[i] + secondLine[j] + secondLine[k]
      if(sum > max && sum <= M) {
        max = sum
      }
 
      // 규칙에 맞는 숫자가 나온 경우에 더이상 계산을 할 필요가 없기 떄문에 종료한다.
      if(max == M) {
        break;
      }
    }
  }
}
 
console.log(max)
 
cs
반응형
반응형

문자열 String에서 영대소문자, 숫자를 제외하고 나머지 문자를 치환하는 경우를 많이 사용하는 방법.

 

 

1
2
3
4
5
String.prototype.cleanup = function () {
  return this.toLowerCase().replace(/[^a-zA-Z0-9]+/g, "_");
};
 
"abc!@!#!@!#".cleanup()
cs

 

기존 String object에 다음과 같은 Cleanup 함수를 추가해서 처리를 할 수 있다.

 

위와 같은 기능이 프로젝트내에서 자주 사용이 된다면,

이런 방법도 좋은 방법이 될 수 있다.

반응형

+ Recent posts