728x90

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

😢 알고리즘을 단계별로 풀었다면, 앞의 지식들을 이용해서 풀어주면 쉽게 가능하다.
코드가 조금 긴 것 같아서, Code Refactoring이 가능할지 고민해 봐야겠다.

😊
산술 평균: arr.reduce함수로 값을 더하고, 2로 나눈 후 Math.round()로 반올림 해주면 된다.
중앙 값: 입력받은 값은 sort()해준 후, Math.floor(arr.length / 2) 해준 것을 index로 넣어주면 된다.
최빈 값: 빈도 별로 Map 생성 - arr.push(최빈 값) - 여러개라면 sort 후(Map을 생성하면서 순서가 바뀌기 때문) index 1(2번 째니까)
아니라면 index 0(1개니까)
범위: sort된 입력값의 마지막 인덱스(arr.length-1) - 입력값의 첫 번째 인덱스(0) 해주면 된다.

728x90

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

 

😢 666, 1666, ..., 9666의 모습만 보면 안되고, 그 이상의 숫자를 예측해봐야 한다.

😊 다음과 같은 로직으로 문제를 해결했다.
1. 첫 번째 종말의 숫자는 666 이므로 665부터 숫자를 계속 증가시킨다.
2. 만약 증가시킨 숫자에 연속된 666이 포함된다? 그러면 input으로 받은 숫자를 1개만큼 줄인다.
3. input이 0이되면 증가를 중단하고 출력해준다.

 

728x90

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

Code

최종 제출 코드

😢 '백준 4673번: 셀프넘버'를 풀었다면 쉽게 풀 수 있는 문제

😊 브루트 포스로 1부터 생성자가 있는 숫자들을 구해주고( d(n) ), N의 생성자가 여러 개라면 배열에 넣어준다.
최종적으로 생성자가 있다면 Math.min을 이용해 최솟값을 출력해주고, 없다면 0을 출력해주면 된다.
각 자릿수를 합하는 것은 위의 셀프넘버를 참고하면 된다.

참고로, 속도는 while로 자릿수를 나누는 게 더 빠르다(Full Code의 2nd Solution code 참고)

Full Code (https://github.com/DasolPark/Dasol_JS_Algorithm/tree/master/Baekjoon)

// Sum of break up(분해합)
 
// 1st Solution
 
// For submit
 
// const fs = require('fs');
// const input = parseInt(fs.readFileSync('/dev/stdin').toString().trim());
 
// For local test
const input = 216;
const constructorArr = [];
 
function d(n) {
const N = n.toString().split('');
 
return n + N.reduce((acc, num) => (acc += parseInt(num)), 0);
}
 
for (let i = 1; i <= input; i++) {
if (d(i) === input) {
constructorArr.push(i);
}
}
 
if (constructorArr.length) {
console.log(Math.min.apply(null, constructorArr));
} else {
console.log(0);
}
 
// 2nd Solution
 
// For submit
 
// const fs = require('fs');
// const input = parseInt(fs.readFileSync('/dev/stdin').toString().trim());
 
// For local test
// const input = 216;
// const constructorArr = [];
 
// function d(n) {
// let temp = n;
// let sum = n;
 
// while (temp) {
// sum += temp % 10;
// temp = parseInt(temp / 10);
// }
 
// return sum;
// }
 
// for (let i = 1; i <= input; i++) {
// if (d(i) === input) {
// constructorArr.push(i);
// }
// }
 
// if (constructorArr.length) {
// console.log(Math.min.apply(null, constructorArr));
// } else {
// console.log(0);
// }
728x90

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

Code

최종 제출 코드

😢 말 그대로 브루트 포스

😊 어떠한 요행을 바라기보다는 그냥 브루프 포스다.
반복문 돌려서 모든 경우의 수를 다 계산한다.

카드 3개의 조합의 합을 구해야 하므로 3개의 중첩 for loop을 이용해 해결 가능하다.

5 6 7 8 9 카드들을 위의 중첩문으로 실행하면 다음과 같은 순서로 진행된다.

[0][1][2] 5 6 7 = 18
[0][1][3] 5 6 8 = 19
[0][1][4] 5 6 9 = 20
[0][2][3] 5 7 8 = 20
[0][2][4] 5 7 9 = 21
[0][3][4] 5 8 9 = 22
[1][2][3] 6 7 8 = 21
[1][2][4] 6 7 9 = 22
[1][3][4] 6 8 9 = 23
[2][3][4] 7 8 9 = 24

위의 합 중에 M보다 작거나 같은 것은 21

Full Code (https://github.com/DasolPark/Dasol_JS_Algorithm/tree/master/Baekjoon)

// Blackjack
 
// For submit
 
// const fs = require('fs');
// const input = fs.readFileSync('/dev/stdin').toString().trim().split('\n');
 
// For local test
const input = ['5 21', '5 6 7 8 9'];
const NM = input
.shift()
.split(' ')
.map(num => parseInt(num));
const N = NM.shift();
const M = NM.shift();
const cardArr = input
.shift()
.split(' ')
.map(num => parseInt(num));
let max = 0;
 
for (let i = 0; i < N - 2; i++) {
for (let j = i + 1; j < N - 1; j++) {
for (let k = j + 1; k < N; k++) {
let sum = cardArr[i] + cardArr[j] + cardArr[k];
if (sum > max && sum <= M) {
max = sum;
}
}
}
}
 
console.log(max);
728x90

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

Code

최종 제출 코드

😢 기본 문제

😊 JavaScript built-in method인 sort()를 사용해주면 된다.
문자를 정렬할 때는 sort()를 그냥 써줘도 되지만, 숫자를 정렬할 때는 sort((a, b) => a-b); 로 써줘야 한다.
난 for ... of를 사용하고 좋아하지만, 속도(?)와 참고하는 사람들 때문에 정석 버전으로 캡쳐했다.

Full Code (https://github.com/DasolPark/Dasol_JS_Algorithm/tree/master/Baekjoon)

// Sort numbers(Ascending order)
 
// For submit
 
// const fs = require('fs');
// const input = fs.readFileSync('/dev/stdin').toString().trim().split('\n').map(num => parseInt(num));
 
// For local test
const input = [5, 5, 2, 3, 4, 1];
const N = input.shift();
const sorted = input.sort((a, b) => a - b);
 
for (let i = 0; i < N; i++) {
console.log(sorted[i]);
}
 
// For submit
 
// const fs = require('fs');
// const input = fs.readFileSync('/dev/stdin').toString().trim().split('\n').map(num => parseInt(num));
 
// For local test
// const input = [5, 5, 2, 3, 4, 1];
// input.shift();
// const sorted = input.sort((a, b) => a - b);
 
// for (let num of sorted) {
// console.log(num);
// }
728x90

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

Code

최종 제출 코드

😢 택시 기하학과 유클리드 기하학을 검색한 후, 이해하고 풀면 되는 문제

😊 유클리드 기하학에서 반지름이 R인 원이 넓이'반지름*반지름*PI'이므로 Math.powMath.PI를 이용하여 풀었고,
택시 기하학에서 반지름이 R인 원의 넓이마름모와 같으므로, '밑변*높이*2'(직사각형 넓이*2라고 생각)로 풀어주면 된다.

Full Code (https://github.com/DasolPark/Dasol_JS_Algorithm/tree/master/Baekjoon)

// Taxi geometry(Euclid geometry)
 
// For submit
 
// const fs = require('fs');
// const input = parseInt(fs.readFileSync('/dev/stdin').toString().trim());
 
// For local test
const input = 1;
 
function Euclid(radius) {
return Math.pow(radius, 2) * Math.PI;
}
 
function taxi(radius) {
return Math.pow(radius, 2) * 2;
}
 
console.log(Euclid(input).toFixed(6));
console.log(taxi(input).toFixed(6));
728x90

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

Code

최종 제출 코드

😢 이쁘게 풀어주려다가 그냥 조건문으로 끝낸 문제

😊 가끔은 단순한게 좋은 방법인듯 하다.

일단 x좌표가 같은 것이 있다면, 이미 평행한 좌표가 있는 것이고
y좌표가 같은 것이 있다면, 역시 평행한 좌표가 있는 것이다.
따라서, x 또는 y가 한 번만 존재하는 좌표를 찾아내고 그 값을 넣어주면 된다.

Full Code (https://github.com/DasolPark/Dasol_JS_Algorithm/tree/master/Baekjoon)

// Fourth coordinate(in a rectangle)
 
// For submit
 
// const fs = require('fs');
// const input = fs.readFileSync('/dev/stdin').toString().trim().split('\n');
 
// For local test
const input = ['30 20', '10 10', '10 20'];
const strToInt = input.map(coords =>
coords.split(' ').map(num => parseInt(num))
);
 
let x = 0;
let y = 0;
if (strToInt[0][0] !== strToInt[1][0]) {
if (strToInt[0][0] !== strToInt[2][0]) {
x = strToInt[0][0];
} else {
x = strToInt[1][0];
}
} else {
x = strToInt[2][0];
}
 
if (strToInt[0][1] !== strToInt[1][1]) {
if (strToInt[0][1] !== strToInt[2][1]) {
y = strToInt[0][1];
} else {
y = strToInt[1][1];
}
} else {
y = strToInt[2][1];
}
 
console.log(`${x} ${y}`);
728x90

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

Code

최종 제출 코드

😢 이렇게 쉬울 거라고 생각하지 못 했던 문제

😊 x, y는 현재 나의 위치이며 w, h는 직사각형의 오른쪽 위 꼭짓점, 0,0은 왼쪽 아래 꼭짓점이다.

                  10,3
(w, h)
          6,2
(x, y)
       
0,0

                 

위 표을 좌표계라고 생각해보자. 그리고 벗어날 수 있는 모든 경우의 수를 배열에 저장해보자.
좌표 0,0 기준으로 직사각형을 벗어나려면 x, y값 그 자체로 움직여야 벗어날 수 있으므로 [x, y]를 배열에 우선 넣는다.(x-0, y-0)
좌표 w, h 기준으로 직사각형을 벗어나려면 w-x, h-y만큼 움직여야 벗어날 수 있다. 따라서, [w-x, h-y]를 추가적으로 배열에 넣는다.

결과적으로 [ x, y, w-x, h-y ] 총 4개의 경우의 수를 구할 수 있다(직사각형을 벗어날 수 있는 이동 값)
최종적으로 Math.min.apply(null, 배열)넣어서 최소값을 구하고 출력해주면 된다.

Full Code (https://github.com/DasolPark/Dasol_JS_Algorithm/tree/master/Baekjoon)

// Escape from Rectangle
 
// For submit
 
// const fs = require('fs');
// const input = fs.readFileSync('/dev/stdin').toString().trim().split(' ').map(num => parseInt(num));
 
// For local test
const input = [6, 2, 10, 3]; // x y w h
const x = input[0];
const y = input[1];
const w = input[2];
const h = input[3];
const counters = [x, y, w - x, h - y];
 
console.log(Math.min.apply(null, counters));
728x90

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

Code

최종 제출 코드

😢 이런 저런 패턴이 많이 보여서, 어떤 패턴으로 접근할 지 고민을 많이 했다.

😊 문제의 의도는 a-1층의 1호부터 b호까지 모두 더하라는 것이 아닐 것이다. 물론 더해도 된다. 하지만 시간이 오래 걸린다.

1 6 21 56 126
1 5 15 35 70
1 4 10 20 35
1 3 6 10 15
1 2 3 4 5

예를 들기 위해, 4층, 1-5호까지 있는 아파트를 표로 작성해봤다(참고로 층은 0부터 시작한다)
어떤 패턴이 있는지 잘 살펴보면, [a행, b열]에 있는 값은 [a행, b-1열] + [a-1행, b열]의 값으로 이루어져 있다.

또한, 가장 아래 행의 각 열은 1부터 b까지 1씩 순차적으로 증가하는 값을 가지며, 왼쪽의 첫 번째 열은 항상 1 값만 갖는다.

입력으로 a=2, b=3을 받았다고 가정해보자
[2, 2] == 4, [1, 3] == 6이라는 것을 알 수 있고, 이 값을 더하면 4+6=10. 곧, [2, 3]의 값이다.
이 패턴을 가지고 코드를 작성해보면 위의 코드가 나온다.

외부 for loop에서 배열을 항상 [1]부터 시작하도록 초기화해준다.
내부 for loop에서는 가장 아래 행이면 1씩 증가하도록 if 조건문을 걸어주고,
그 외 경우는 위의 [a행, b-1열] + [a-1행, b열] 패턴에 맞도록 값을 저장해준다.
그리고 마지막에 알고 싶은 층과 호수배열의 인덱스에 넣고 찾아주면 된다.

Full Code (https://github.com/DasolPark/Dasol_JS_Algorithm/tree/master/Baekjoon)

 
// I'll be the president of the women's association
 
// 2nd Solution - Good
 
// For submit
 
// const fs = require('fs');
// const input = fs.readFileSync('/dev/stdin').toString().trim().split('\n').map(num => Number(num));
 
// For local test
const input = [2, 1, 3, 2, 3];
const T = input.shift();
 
for (let i = 0; i < T; i++) {
const a = input.shift();
const b = input.shift();
const apartment = [];
 
for (let i = 0; i <= a; i++) {
apartment.push([1]);
for (let j = 1; j < b; j++) {
if (i === 0) {
apartment[i].push(j + 1);
} else {
apartment[i].push(apartment[i][j - 1] + apartment[i - 1][j]);
}
}
}
 
const floor = a;
const room = b - 1;
console.log(apartment[floor][room]);
}
 
728x90

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

Code

제출 코드(머릿속으로 이해가 끝난 후)

 

제출 코드(직관적으로 보기 좋은 코드)

😢 어떻게 빠르게 해당 집단을 찾아낼 것인지, 해당 집안에서 정답을 어떻게 도출할 것인지가 핵심

😊 2번째 제출코드를 먼저 보면 이해하기 편하다.

다음 표는 지그재그 순서로 진행하는 분수를 더 보기 편하게 정리한 것이다.

1/1          
1/2 2/1        
3/1 2/2 1/3      
1/4 2/3 3/2 4/1    
5/1 4/2 3/3 2/4 1/5  
... ... ... ... ... ...

분모짝수일 때, 오름차순으로(1 2 3 4 5...) 숫자가 진행되는 것을 알 수 있고,
분자짝수일 때, 내림차순으로(5 4 3 2 ...) 숫자가 진행되는 것을 알 수 있다. 홀수는 그 반대다.

패턴을 파악했으니, 어떻게 답을 찾아낼 지 생각해보자.

먼저, 최대로 입력받을 수 있는 수의 크기는 10,000,000이므로 배열이나 테이블로 만드는 건 시간 초과가 날 것이다.
따라서, 찾고자하는 X번을 포함하고 있는 그룹을 찾고, 그 그룹 안에서 X번째 분모/분자 값을 찾아내야 한다.

1/1부터 시작한다고 생각할 때, 해당 그룹의 분수 개수는 1부터 1씩 증가한다.
그룹 개수가 증가할 때마다 입력 받은 X에서 그룹을 빼주면 해당 그룹에 도달했을 때, X는 0 또는 음수가 된다.
위 과정을 while문에서 진행해주면 된다.

여기서 중요한 것은 groupCounter가 곧 해당 그룹의 분수 개수라는 것이다. 이 것을 기억하고 다음 단계로 넘어가보자.

이제 if (group % 2 === 0)을 이용해서 짝수일때, 분모 출력groupCounter + X 로 해주면
해당 그룹의 끝 기준으로 자신의 순번을 찾는다.(12345 처럼 오름차순 기준이기 때문)
그리고 분자1 + (-X) 를 해주면 역시 그룹의 끝 기준으로 자신의 순번을 찾는다.( 54321처럼 내림차순이기 때문)

예를 들어 11번째 분수를 찾아보자.

while(X > 0){} 코드를 통해 groupCounter는 5, X는 -4라는 것을 알아낼 수 있다.
그룹은 5번째이므로 홀수이기 때문에, 분모는 내림차순, 분자는 오름차순이다.
분모 그룹은 54321
분자 그룹은 12345
이며 분모는 1+ -(-4) = 5이므로, 5번째 그룹의 1번째 수이며,
분자는 5 + (-4) = 1이므로, 역시 5번째 그룹의 1번째 수다.

Full Code (https://github.com/DasolPark/Dasol_JS_Algorithm/tree/master/Baekjoon)

// Find Fraction
 
// 1st Solution
 
// For submit
 
// const fs = require('fs');
// const X = Number(fs.readFileSync('/dev/stdin').toString().trim());
 
// For local test
let X = 14;
let counter = 0;
 
while (X > 0) {
counter++;
X = X - counter;
}
 
if (counter % 2 === 0) {
console.log(`${counter + X}/${1 + -X}`);
} else {
console.log(`${1 + -X}/${counter + X}`);
}
 
// 2nd Solution
 
// For submit
 
// const fs = require('fs');
// let X = Number(fs.readFileSync('/dev/stdin').toString().trim());
 
// For local test
// let X = 11;
// let groupCounter = 0;
// let ascendingNumArr = [];
// let descendingNumArr = [];
 
// while (X > 0) {
// groupCounter++;
// X = X - groupCounter;
// }
 
// for (let i = 0; i < groupCounter; i++) {
// ascendingNumArr.push(i + 1);
// descendingNumArr.push(groupCounter - i);
// }
 
// if (groupCounter % 2 === 0) {
// console.log(
// `${ascendingNumArr[groupCounter - 1 + X]}/${
// descendingNumArr[groupCounter - 1 + X]
// }`
// );
// } else {
// console.log(
// `${descendingNumArr[groupCounter - 1 + X]}/${
// ascendingNumArr[groupCounter - 1 + X]
// }
// `
// );
// }

+ Recent posts