
https://softeer.ai/practice/9657
slice쓰지말고 그냥 0대입해라.
생각보다는 오래 걸렸지만 이냥저냥 Lv.2라 그런지 풀만했던 문제
const fs = require('fs');
const input = fs.readFileSync('/dev/stdin').toString().trim().split('\n');
function solution() {
// 1. 첫 번째 줄: 행(n)과 열(m)
const [n, m] = input[0].split(' ').map(Number);
// 2. 지도 데이터
const maps = [];
for (let i = 1; i <= n; i++) {
maps.push(input[i].split(' ').map(Number));
}
// 3. 시작점과 끝점
const start = input[n + 1].split(' ').map(Number);
const end = input[n + 2].split(' ').map(Number);
const attackRange = [start, end];
// [사냥꾼 카운팅]
let hunter = 0;
for (let i=0; i < n; i++) {
for(let j=0; j<m; j++) {
if(maps[i][j] === 1) {
hunter++
}
}
}
// 주어진 시작점(start)부터 끝점(end)까지 반복문을 돌며
// map의 attack의 범위에 대해 j가 1을 만났을 때
// 1을 0으로 바꾸어주고 그떄 바꾼 값을 카운팅
let cnt = 0;
for (let attck of attackRange) {
for (let i=attck[0]-1; i < attck[1]; i++) {
for(let j=0; j<m; j++) {
if(maps[i][j] === 1) {
maps[i][j] = 0;
cnt++
break;
}
}
}
}
console.log(hunter - cnt)
}
solution();
const fs = require('fs');
const input = fs.readFileSync('/dev/stdin').toString().trim().split('\n');
function solution() {
// 1. 첫 번째 줄: 행(n)과 열(m)
const [n, m] = input[0].split(' ').map(Number);
// 2. 지도 데이터
const maps = [];
for (let i = 1; i <= n; i++) {
maps.push(input[i].split(' ').map(Number));
}
// 3. 시작점과 끝점
const start = input[n + 1].split(' ').map(Number);
const end = input[n + 2].split(' ').map(Number);
// 공격 범위 배열
const attackRange = [start, end];
// 4. 초기 몬스터 개수 계산 함수
const countMonsters = () => {
let count = 0;
for (const row of maps) {
for (const cell of row) {
if (cell === 1) count++;
}
}
return count;
};
// 5. 공격 로직 함수
const attackMonsters = (attackRange) => {
let defeated = 0;
for (const [start, end] of attackRange) {
for (let i = start - 1; i < end; i++) { // 1-based → 0-based 변환
for (let j = 0; j < m; j++) {
if (maps[i][j] === 1) {
maps[i][j] = 0; // 몬스터 제거
defeated++;
break; // 해당 행은 탐색 종료
}
}
}
}
return defeated;
};
// 6. 계산
const initialCount = countMonsters(); // 초기 몬스터 개수
const defeatedMonsters = attackMonsters(attackRange); // 제거된 몬스터 개수
// 7. 결과 출력
console.log(initialCount - defeatedMonsters);
}
solution();
완전 어이없는 문제.. 태어나서 예시 TC가 틀리지만 문제가 맞는 경우가 없기에 한참 동안 고쳤었따..
const fs = require('fs');
const input = fs.readFileSync('/dev/stdin').toString().trim().split('');
function solution() {
let ans = [];
let stack = [];
ans.push(input[0])
stack.push(input[0])
for(let i=1; i<input.length; i++) {
if (input[i] === '(') {
ans.push(input[i]);
stack.push(input[i]);
} else {
stack.pop();
stack[stack.length-1] === '(' && stack.length%2 === 1 ? ans.push('1+1') : ans.push('1')
ans.push(input[i])
if (i !== input.length-1) ans.push('+')
}
}
console.log(ans.join(''))
}
solution()
전형적인 stack문제로 어떻게 stack이 들어가고 어떤 값이 와야하는지 떠올리면 금방 쉽게 풀 수 있음
n*n의 false로 된 2차원 배열을 만들고 싶을 때
따온 input을 바로 넣으면 문자열이라
1차원의 false배열이 만들어졌었음
소프티어에서 visited를 만들 땐 꼭 n의 값을 parseInt로 바꿔주기
겁나 어이없음
그냥 각 구역을 나누는 방법을 따지면 되는 거라
아래가 정답이라고 함
그 아래 풀이는 열심히 bfs로 풀었떤 경우
const fs = require('fs')
const input = fs.readFileSync('/dev/stdin').toString().trim().split('\n');
const n = parseInt(input[0]);
for (let i = 0; i < n; i++) {
console.log(Array(n).fill(i + 1).join(' '));
}
const fs = require('fs');
const input = fs.readFileSync('/dev/stdin').toString().trim().split('\n');
function solution() {
const n = parseInt(input[0]); // 보드 크기
const maps = [];
for (let i = 1; i <= n; i++) {
maps.push(input[i].split(' ').map(Number));
}
// 방문 여부 및 결과 배열 초기화
let visited = Array.from({ length: n }, () => Array(n).fill(false));
let result = Array.from({ length: n }, () => Array(n).fill(0));
let regionId = 1; // 구역 번호 시작
// 방향 벡터 (상, 우, 하, 좌)
const dx = [-1, 0, 1, 0];
const dy = [0, 1, 0, -1];
// 모든 칸 순회
for (let i = 0; i < n; i++) {
for (let j = 0; j < n; j++) {
// 방문하지 않은 칸에서 새로운 구역 시작
if (!visited[i][j]) {
let queue = [];
queue.push([i, j]); // 시작점 추가
visited[i][j] = true;
result[i][j] = regionId;
let cells = [[i, j]]; // 현재 구역의 좌표 저장
let usedNumbers = new Set([maps[i][j]]); // 구역 내 숫자 중복 방지
while (queue.length) {
const [x, y] = queue.shift();
// 상, 우, 하, 좌 탐색
for (let d = 0; d < 4; d++) {
const nx = x + dx[d];
const ny = y + dy[d];
// 유효한 좌표인지 확인
if (nx >= 0 && nx < n && ny >= 0 && ny < n) {
// 방문하지 않았고, 숫자가 중복되지 않으면 추가
if (!visited[nx][ny] && !usedNumbers.has(maps[nx][ny])) {
queue.push([nx, ny]);
visited[nx][ny] = true;
result[nx][ny] = regionId;
cells.push([nx, ny]);
usedNumbers.add(maps[nx][ny]);
// 구역 크기가 n이면 탐색 종료
if (cells.length === n) break;
}
}
}
}
regionId++; // 새로운 구역 번호 증가
}
}
}
// 결과 출력
result.forEach(row => console.log(row.join(" ")));
}
solution();
let max = 0; // 결과값 (최대 배수 카운트)
// 2부터 배열 최대값까지 반복
for (let i = 2; i <= largist; i++) {
let cnt = 0;
for (let j = 0; j < n; j++) {
if (charcolls[j] % i === 0) {
cnt++;
if (cnt >= max) {
max = cnt
}
}
}
}
난 그냥 바보똥멍청이다.
결과적으로 가장 큰 차이는 배열 전체를 순회 하느냐 아니면 배열의 가장 작은값~큰값까지 1씩 증가시키며 하는 차이였음
나는 당연하게도 배열의 인덱스에 접근해서 하나하나 상승시켰지만 사실 그게아닌
오름차순 정렬 후 2부터 가장 큰 애까지 반복시키며 거기에서 얼마나 카운트가 되는지 찾는 게 핵심이었다.
위에가 정답 코드 아래가 멍청이 코드라 하자
const fs = require('fs');
const input = fs.readFileSync('/dev/stdin').toString().trim().split('\n');
function solution() {
const n = parseInt(input[0]);
const charcolls = input[1].split(' ').map(Number).sort( (a, b) => a-b );
const largist = charcolls[charcolls.length-1]
let max = 0; // 결과값 (최대 배수 카운트)
// 2부터 배열 최대값까지 반복
for (let i = 2; i <= largist; i++) {
let cnt = 0;
for (let j = 0; j < n; j++) {
if (charcolls[j] % i === 0) {
cnt++;
if (cnt >= max) {
max = cnt
}
}
}
}
console.log(max);
}
solution();
const fs = require('fs');
const input = fs.readFileSync('/dev/stdin').toString().trim().split('\n')
function solution() {
const n = input[0];
const charcolls = input[1].split(' ').map(Number).sort((a,b) => a-b);
// 주어진 숫자 배열에 따라서
// 각 숫자의 배수가 가장 많은 애의 cnt를 리턴하면 됨
let max = 1;
for(let i=0; i<n; i++) {
let target = charcolls[i];
let cnt = 1;
for (let j=i+1; j<n; j++) {
if(charcolls[j] % target === 0) {
cnt++
if (cnt >= max) {
max = cnt;
}
// console.log('max', max)
// console.log('cnt', cnt)
}
}
}
console.log(max)
}
solution()
const row = maps[i]
console.log(row.every( v => v === row[0]))
진짜 겁나 하나도 뭐라는지 너무 꼬이고 꼬인 문제라고 생각이 들었지만 시간이 충분했따면 조금 더 쉽게 접근했을 문제
const fs = require('fs');
const input = fs.readFileSync('/dev/stdin').toString().trim().split('\n');
function solution() {
// 3x3 배열로 입력 받기
const maps = input.map(line => line.split(' ').map(Number));
// 세 개의 숫자에서 중간값을 찾아 비용 계산하는 함수
function calculateCost(a, b, c) {
const values = [a, b, c];
const middle = values.sort((x, y) => x - y)[1]; // 중간값
return Math.abs(middle - a) + Math.abs(middle - b) + Math.abs(middle - c); // 비용 계산
}
let res = Infinity; // 결과값 초기화
// 가로 방향 확인
for (let i = 0; i < 3; i++) {
const [firstIndex, secondIndex, thirdIndex] = maps[i];
if (firstIndex === secondIndex && secondIndex === thirdIndex) {
console.log(0);
return;
} else {
const tmp = calculateCost(firstIndex, secondIndex, thirdIndex);
res = Math.min(res, tmp);
}
}
// 세로 방향 확인
for (let i = 0; i < 3; i++) {
const col = [maps[0][i], maps[1][i], maps[2][i]];
if (col[0] === col[1] && col[1] === col[2]) {
console.log(0);
return;
} else {
const tmp = calculateCost(col[0], col[1], col[2]);
res = Math.min(res, tmp);
}
}
console.log(res); // 최소 비용 출력
}
solution();
const jew = input.slice(1);
['100 2', '90 1', '70 2'] => ['90 1', '70 2']
const fs = require('fs');
const input = fs.readFileSync('/dev/stdin').toString().trim().split('\n');
function solution() {
let [bag, category] = input[0].split(' ').map(Number);
let jew = input.slice(1).map(value => value.split(' ').map(Number)).sort( (a, b) => b[1] - a[1]);
let maxPrice = 0;
for(let i=0; i<jew.length; i++) {
let count = jew[i][0];
let price = jew[i][1];
let sell = Math.min(bag, count)
maxPrice += price * sell;
bag -= sell;
if(bag === 0) break
}
console.log(maxPrice)
}
solution();
생각한대로 쉬웠지만 한 가지 간과한 사실이 있었다
let sell = Math.min(bag, count) 를 통해 누가 빨리 품절되는지 확인이 가능하다는 것
수학적으로 조금 더 다가가면 좋을 것 같다.
MOD = 1000000007;
const fs = require('fs');
const input = fs.readFileSync('/dev/stdin').toString().trim().split(' ').map(Number)
const solution = () => {
let virus = input[0];
const multiple = input[1];
const times = input[2];
const MOD = 1000000007
for(let i=1; i<=times; i++) {
virus = (virus * multiple) % MOD;
}
console.log(virus)
}
solution();
위 결과도 맞지만 제약조건이 매우 크기떄문에 빠른 제곱 연산을 활용해야 한다고 함
const fs = require('fs');
const input = fs.readFileSync('/dev/stdin').toString().trim().split(' ').map(BigInt);
function solution() {
const MOD = 1000000007n; // 모듈러 값
let [K, P, N] = input; // K: 초기 바이러스 수, P: 증가율, N: 시간
let result = 1n; // P^N 값을 계산하기 위한 초기값
let base = P; // P^1부터 계산하기 위한 초기 base 값
// 빠른 거듭제곱 방식으로 P^N % MOD 계산
while (N > 0n) {
if (N % 2n === 1n) {
result = (result * base) % MOD; // 현재 base를 곱함
}
base = (base * base) % MOD; // base를 제곱
N = N / 2n; // 지수를 반으로 줄임
}
// 최종 바이러스 수 계산: (K * P^N) % MOD
const total = (K * result) % MOD;
console.log(total.toString()); // 결과 출력
}
solution();
const fs = require('fs');
const input = fs.readFileSync('/dev/stdin').toString().trim().split(' ').map(Number)
function solution() {
const ascending = [1, 2, 3, 4, 5, 6, 7, 8];
const descending = [8, 7, 6, 5, 4, 3, 2, 1];
if (JSON.stringify(input) === JSON.stringify(ascending)) {
console.log("ascending");
} else if (JSON.stringify(input) === JSON.stringify(descending)) {
console.log("descending");
} else {
console.log("mixed");
}
}
solution()
맨 처음에 every, 그리고 sort를 이용하여 풀다가 오답이 나왔는데 그 이유가 stringfy를 해주지 않아서 그런 것 같다
=> 각각의 출발점을 조사할 때도 필요하니까
내 기존 코드
const fs = require('fs');
const input = fs.readFileSync('/dev/stdin').toString().trim().split('\n')
function solution() {
const n = parseInt(input[0])
let ans = [];
let maps = [];
for (let i=1; i <= n; i++) {
maps.push(input[i].split('').map(Number))
}
let visited = [];
for(let i=0; i<n; i++) visited.push(new Array(n).fill(false))
let startPos = [];
for(let i=0; i<n; i++) {
if (startPos.length === 1) break;
for(let j=0; j<n; j++) {
if(maps[i][j] === 1) {
startPos.push([i,j]);
break;
}
}
}
visited[startPos[0][0]][startPos[0][1]] = true;
// maps[startPos[0][0]][startPos[0][1]] = 2;
let queue = [];
queue.push([startPos[0][0], startPos[0][1]])
const dx = [-1, 0, 1 ,0];
const dy = [0, 1, 0, -1];
let junk = 2;
let reStartPos = [];
while(queue.length) {
const [x, y] = queue.shift();
maps[x][y] = junk;
let cnt = 0;
for(let i=0; i<4; i++) {
let nx = x + dx[i];
let ny = y + dy[i];
if (nx >= 0 && nx < n && ny >= 0 && ny < n && !visited[nx][ny] && maps[nx][ny] === 1) {
cnt++;
visited[nx][ny] = true;
// maps[nx][ny] = maps[x][y] + 1
maps[nx][ny] = junk
queue.push([nx, ny])
}
}
if(!queue.length) {
for(let i=0; i<n; i++) {
if (queue.length === 1) break;
for(let j=0; j<n; j++) {
if(maps[i][j] === 1) {
queue.push([i,j]);
break;
}
}
}
}
junk++;
}
console.log('maps', maps)
}
solution()
const fs = require('fs');
const input = fs.readFileSync('/dev/stdin').toString().trim().split('\n');
function solution() {
const n = parseInt(input[0]);
let maps = [];
for (let i = 1; i <= n; i++) {
maps.push(input[i].split('').map(Number));
}
let visited = Array.from({ length: n }, () => Array(n).fill(false));
const dx = [-1, 0, 1, 0];
const dy = [0, 1, 0, -1];
let junk = 2; // 덩어리마다 다른 숫자로 표시
for (let i = 0; i < n; i++) {
for (let j = 0; j < n; j++) {
if (maps[i][j] === 1 && !visited[i][j]) {
let queue = [[i, j]];
visited[i][j] = true;
maps[i][j] = junk;
while (queue.length) {
const [x, y] = queue.shift();
for (let k = 0; k < 4; k++) {
let nx = x + dx[k];
let ny = y + dy[k];
if (nx >= 0 && nx < n && ny >= 0 && ny < n && !visited[nx][ny] && maps[nx][ny] === 1) {
visited[nx][ny] = true;
maps[nx][ny] = junk;
queue.push([nx, ny]);
}
}
}
junk++; // 다음 덩어리는 새로운 숫자로 표시
}
}
}
console.log('maps', maps);
}
solution();
오랜만에 제대로된 BFS의 덩어리 문제를 찾았다
하지만 처음엔 while안에다가 이중 포문을 넣어 뭐가 문제인지 모르는 체로 계속헤매다가 예전에 풀었던 덩어리 찾기에서 힌트를 얻고 이중 포문안에 넣는 방법을 떠올렸다
생각해보면 당연히 이중포문을 통해 앞에서부터 접근한다면 여러가지 전처리 기능을 바로바로 해결할 수 있었던 장점이 있는 것 같다
const fs = require('fs');
const input = fs.readFileSync('/dev/stdin').toString().trim().split('\n');
function solution() {
const n = parseInt(input[0]);
let maps = [];
for (let i = 1; i <= n; i++) {
maps.push(input[i].split('').map(Number));
}
let visited = [];
for (let i = 0; i < n; i++) {
visited.push(new Array(n).fill(false));
}
let queue = [];
const dx = [-1, 0, 1, 0];
const dy = [0, 1, 0, -1];
let junk = 2;
let cnt = 1;
let ans = [];
for (let i = 0; i < n; i++) {
for (let j = 0; j < n; j++) {
if (maps[i][j] === 1 && !visited[i][j]) {
queue.push([i, j]);
visited[i][j] = true;
maps[i][j] = junk;
while (queue.length) {
const [x, y] = queue.shift();
for (let k = 0; k < 4; k++) {
let nx = x + dx[k];
let ny = y + dy[k];
if (nx >= 0 && nx < n && ny >= 0 && ny < n && !visited[nx][ny] && maps[nx][ny] === 1) {
cnt++;
visited[nx][ny] = true;
maps[nx][ny] = junk;
queue.push([nx, ny]);
}
}
}
ans.push(cnt); // 단지의 크기를 ans에 추가
junk++;
cnt = 1; // 다음 단지를 위해 카운트 초기화
}
}
}
ans.sort( (a, b) => a-b)
console.log(ans.length); // 단지의 수 출력
for (let i = 0; i < ans.length; i++) {
console.log(ans[i]); // 각 단지의 크기 출력
}
}
solution();
우선 코드는 위와 같고
const fs = require('fs');
const input = fs.readFileSync('/dev/stdin').toString().trim();
function solution() {
const n = parseInt(input)
console.log(Math.pow(Math.pow(2, n)+1, 2))
}
solution()
징검다리 비밀메뉴 조립라인
엥 그냥 포함관계 확인하면 되는 너무 쉬운 문제..
// 첫쨰줄 -> 비밀 버튼 갯수, 버튼 조작 갯수, 최대값
// 두번쨰줄 -> 조작 방법
// K -> 버튼 갯수
const fs = require('fs');
const input = fs.readFileSync('/dev/stdin').toString().trim().split('\n')
function solution() {
const [m, n, k] = input[0].split(' ').map(Number)
const method = input[1].split(' ').join('')
const controll = input[2].split(' ').join('')
console.log(controll.includes(method) ? 'secret' : 'normal')
}
solution()
두 개의 배열이 주어졌을 때 반복문으로 i와 j를 증가하는 것이 아닌 조건에 따라 증가시키는 것
const fs = require('fs');
const input = fs.readFileSync('/dev/stdin').toString().trim().split('\n')
function solution() {
const [n, m] = input[0].split(' ').map(Number)
let targetCos = [];
for (let i=1; i < n+1; i++) targetCos.push(input[i].split(' ').map(Number))
let testCos = [];
for (let i=n+1; i < input.length; i++) testCos.push(input[i].split(' ').map(Number))
// (초기) 타겟의 거리 설정
let i = 0;
let targetDist = targetCos[i][0];
// (초기) 테스트의 거리 설정
let j = 0;
let testDist = testCos[j][0];
// max값을 저장할 변수
let maxSpeed = 0;
// 둘 중 하나가 끝나면 끝
while(i < n && j < m) {
// 타겟의 스피드 설정
let targetSpeed = targetCos[i][1];
// 테스트의 스피드 설정
let testSpeed = testCos[j][1];
// 테스트가 더 크면
if (testSpeed > targetSpeed) {
// 초과한 거리만큼 max값을 계산하여 할당
maxSpeed = Math.max(maxSpeed, testSpeed - targetSpeed);
}
// test의 길이가 더 길 경우
if (testDist > targetDist) {
// 남은 테스트의 길이 설정
testDist = testDist - targetDist;
// 다음 타겟을 위한 i값 증가
i++
// 다음 타겟값 설정
if (i < n) targetDist = targetCos[i][0];
} else if (targetDist > testDist) {
// target의 길이가 더 길 경우 (마찬가지)
targetDist = targetDist - testDist;
j++
if (j < m) testDist = testCos[j][0];
} else {
// 둘 다 동일시 둘다 증가
i++
j++
if (i < n) targetDist = targetCos[i][0];
if (j < m) testDist = testCos[j][0];
}
}
console.log(maxSpeed)
}
solution()
어떻게 보면 쉽고 어떻게 보면 어려웠던 것 같음 (졸려서 그런가)
두 개의 포인터를 각각 놓고 값을 증가시키면서
다음 타겟의 값을 지정해주던
다음 테스트의 값을 지정해주며 나아가면 됨
max관련해서는 더욱 꼼꼼히 살펴봐야할 것 같음
그냥 Map을 한번 써보기 위해 간단하게 풀은 문제..
재직자 대회문제는 그냥 놀자식인지 굳이 안 풀어도 되거나 padStart를 쓰는 문제가 많은 것 같다
const fs = require('fs');
const input = fs.readFileSync('/dev/stdin').toString().trim().split('\n');
function solution() {
const [n, m] = input[0].split(' ').map(Number);
// 9~18까지 비교용 배열
const START_TIME = 9;
const END_TIME = 18;
// 회의실 이름 저장
let 회의실 = [];
for (let i = 1; i <= n; i++) 회의실.push(input[i]);
// 회의실 별 예약 정보 저장 (Map 활용)
let 회의실맵 = new Map(회의실.map(회의실이름 => [회의실이름, []]));
// 예약 정보 저장
let 예약정보 = [];
for (let i = n + 1; i < input.length; i++) {
let [회의실이름, start, end] = input[i].split(' ');
start = Number(start);
end = Number(end);
회의실맵.get(회의실이름).push([start, end]);
}
// **출력 포맷 맞추기**
let result = [];
// 회의실 이름을 오름차순 정렬 후 처리
let 정렬된회의실 = [...회의실맵.keys()].sort();
for (let room of 정렬된회의실) {
result.push(`Room ${room}:`);
let 예약된시간 = 회의실맵.get(room);
// 예약된 시간 정렬
예약된시간.sort((a, b) => a[0] - b[0]);
// 빈 시간대 찾기
let availableTimes = [];
let prevEnd = START_TIME;
for (let [start, end] of 예약된시간) {
if (prevEnd < start) {
availableTimes.push(`${String(prevEnd).padStart(2, '0')}-${String(start).padStart(2, '0')}`);
}
prevEnd = end;
}
// 마지막 시간 이후의 빈 시간 체크
if (prevEnd < END_TIME) {
availableTimes.push(`${String(prevEnd).padStart(2, '0')}-${String(END_TIME).padStart(2, '0')}`);
}
// 예약 가능 시간이 없는 경우
if (availableTimes.length === 0) {
result.push("Not available");
} else {
result.push(`${availableTimes.length} available:`);
result.push(...availableTimes);
}
// 마지막 회의실인지 확인 후, 구분선 추가 여부 결정
if (room !== 정렬된회의실[정렬된회의실.length - 1]) {
result.push("-----");
}
}
// 결과 출력
console.log(result.join("\n"));
}
solution();