백준 단계별 - 브루트 포스

박상은·2021년 11월 6일
0

🤔 알고리즘 🤔

목록 보기
12/19

1. 2798번 - 블랙잭

/**
 * 브루트 포스
 * 그냥 무식하게 모든 경우의수를 계산하는 방법
 */
const readline = require("readline");
const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
});

const input = [];

rl.on("line", line => {
  input.push(line.split(" "));

  if (input.length >= 2 && +input[0][0] === input[1].length) rl.close();
}).on("close", () => {
  const targetNumber = +input.shift()[1];
  const cards = input.flat(1).map(v => +v);

  // 정답 기록
  let answer = 0;

  cards.forEach(card1 => {
    cards.forEach(card2 => {
      cards.forEach(card3 => {
        // 중복카드 허용 X
        if (card1 === card2 || card2 === card3 || card1 === card3) return;

        const sum = card1 + card2 + card3;
        if (sum > answer && sum <= targetNumber) answer = sum;
      });
    });
  });

  console.log(answer);

  process.exit();
});

2. 2231번 - 분해합

/**
 * 생성자는 무조건 본인보다 작을 수 밖에 없음 ( 본인 + 각자리수의 합이기 때문에 )
 * 따라서 본인보다 작은 모든 숫자의 분해합을 기록하고 일치하는 것들 중에서 가장 작은 값을 찾아내면 됨
 */
const readline = require("readline");
const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
});

let input = null;

rl.on("line", line => {
  input = +line;

  rl.close();
}).on("close", () => {
  const candidate = Array(input)
    .fill()
    .map((v, i) => {
      // 1부터 시작
      i += 1;

      // 10미만의 자연수는 자기자신이 생성자인줄 알았으나 본인 + 본인 으로 계산해야하네
      if (i < 10) {
        return i * 2;
      } else {
        // 10이상의 자연수는 "자기자신 + 각자리 숫자"연산후 넣기
        return (
          i +
          String(i)
            .split("")
            .reduce((prev, curr) => +prev + +curr)
        );
      }
    });

  // 정답 기록
  let answer = 0;

  // 만족하는놈이 발견되면 반복종료
  candidate.every((v, i) => {
    if (v === input) {
      answer = i + 1;
      return false;
    }
    return true;
  });

  console.log(answer);

  process.exit();
});

3. 7568번 - 덩치

const readline = require("readline");
const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
});

const input = [];

rl.on("line", line => {
  input.push(line);

  if (input.length >= 2 && +input[0] === input.length - 1) rl.close();
}).on("close", () => {
  input.shift();
  const people = input.map(value => value.split(" ").map(v => +v));

  // 정답 기록
  let answer = "";

  people.forEach(person1 => {
    let count = 1;
    people.forEach(person2 => {
      // 본인일 경우 제외
      if (person1 === person2) return;

      if (person1[0] < person2[0] && person1[1] < person2[1]) count++;
    });

    answer += `${count} `;
  });

  console.log(answer);

  process.exit();
});

4. 1018번 - 체스판 다시 칠하기

/**
 * 8 * 8로 짤라서 계산후 배열에 넣고 그중에 가장 작은 값을 출력하는 방식으로 해결
 * 여기서 조금 비효율적으로 만든부분이
 * 시작이 black인지 white인지에 따라서 결과가 달라지기 때문에
 * 한가지 보드판에서 black인경우, white인경우 모두 계산후 배열에 넣는 방식으로 처리함
 *
 * 조금은 비효율적이지만 브루트 포스이니까 상관없다고 생각함
 *
 * 추가로 1개만 색이 다른 경우로 돌려봤는데도 실패라서 어떤 경우의 수가 있는지 정확히 모르겠음
 */
const readline = require("readline");
const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
});

const input = [];
const paintBoard = (board, x, y, initColor) => {
  let count = 0;
  let currentColor = initColor;

  for (let i = x - 7; i <= x; i++) {
    for (let j = y - 7; j <= y; j++) {
      // 같은 색이면 "count++" 하고 색변경
      if (currentColor === board[i][j]) {
        currentColor = !currentColor;
        count++;
        continue;
      }

      currentColor = board[i][j];
    }

    // 라인이 바뀔 때는 같은 색이므로 색변경
    currentColor = !currentColor;
  }

  return count;
};

rl.on("line", line => {
  input.push(line);

  // 대충 지정한 만큼만 입력받도록
  if (input.length >= 2 && +input[0].split(" ")[0] === input.length - 1 && +input[0].split(" ")[1] === input[1].length) rl.close();
}).on("close", () => {
  // 가로, 세로값 얻기
  const [row, column] = input
    .shift()
    .split(" ")
    .map(v => +v);

  // 나중에 변경 편하게 하려고 B => true, W => false로 치환
  const board = input.map(value => value.split("").map(v => v === "B"));
  const results = [];

  // 모든 경우의 수 계산 ( 8 * 8을 모든 구역 나눠서 계산 )
  for (let i = 7; i < row; i++) {
    for (let j = 7; j < column; j++) {
      results.push(paintBoard(board, i, j, true));
      results.push(paintBoard(board, i, j, false));
    }
  }

  // 정답 기록
  let answer = Math.min(...results);

  console.log(answer);

  process.exit();
});

5. 1436번 - 영화감독 숌

const readline = require("readline");
const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
});

let input = null;

rl.on("line", line => {
  input = +line;

  rl.close();
}).on("close", () => {
  // 정답 기록
  let answer = 0;

  let number = 665;
  while (answer !== input) {
    number++;

    const numberList = number
      .toString()
      .split("")
      .map(v => +v);
    const sixCount = numberList.filter(n => n === 6).length;

    // 6이 3개 이상이라면
    if (sixCount >= 3) {
      let count = 0;
      const result = numberList.every(n => {
        if (n === 6) count++;
        else count = 0;

        if (count === 3) return false;
        return true;
      });

      if (!result) answer++;
    }
  }

  console.log(number);

  process.exit();
});

0. 마무리

무작정 모든 경우의 수를 계산하더라도 최소한으로 반복하게 즉, 같은 경우는 반복하지 않도록 최대한 고민을 해봤는데 전부 다 고민한 결과는 실패였음

0개의 댓글