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

 

18258번: 큐 2

첫째 줄에 주어지는 명령의 수 N (1 ≤ N ≤ 2,000,000)이 주어진다. 둘째 줄부터 N개의 줄에는 명령이 하나씩 주어진다. 주어지는 정수는 1보다 크거나 같고, 100,000보다 작거나 같다. 문제에 나와있지

www.acmicpc.net

문제

정수를 저장하는 큐를 구현한 다음, 입력으로 주어지는 명령을 처리하는 프로그램을 작성하시오.

명령은 총 여섯 가지이다.

  • push X: 정수 X를 큐에 넣는 연산이다.
  • pop: 큐에서 가장 앞에 있는 정수를 빼고, 그 수를 출력한다. 만약 큐에 들어있는 정수가 없는 경우에는 -1을 출력한다.
  • size: 큐에 들어있는 정수의 개수를 출력한다.
  • empty: 큐가 비어있으면 1, 아니면 0을 출력한다.
  • front: 큐의 가장 앞에 있는 정수를 출력한다. 만약 큐에 들어있는 정수가 없는 경우에는 -1을 출력한다.
  • back: 큐의 가장 뒤에 있는 정수를 출력한다. 만약 큐에 들어있는 정수가 없는 경우에는 -1을 출력한다.

입력

첫째 줄에 주어지는 명령의 수 N (1 ≤ N ≤ 2,000,000)이 주어진다. 둘째 줄부터 N개의 줄에는 명령이 하나씩 주어진다. 주어지는 정수는 1보다 크거나 같고, 100,000보다 작거나 같다. 문제에 나와있지 않은 명령이 주어지는 경우는 없다.

출력

출력해야하는 명령이 주어질 때마다, 한 줄에 하나씩 출력한다.

예제 입력 1 복사

15
push 1
push 2
front
back
size
empty
pop
pop
pop
size
empty
pop
push 3
empty
front

예제 출력 1 복사

1
2
2
0
1
2
-1
0
1
-1
0
3

 

문제풀이(1)

아래와 같은 큐의 형식으로 구현하는 문제이다.
Javascript의 메서드를 사용해서 구현하게 될 경우 실행시간 초과가 나올 수 있으므로 직접구현하는 방식을 선택했다.
push X: 정수 X를 큐에 넣는 연산이다.
pop: 큐에서 가장 앞에 있는 정수를 빼고, 그 수를 출력한다. 만약 큐에 들어있는 정수가 없는 경우에는 -1을 출력한다.
size: 큐에 들어있는 정수의 개수를 출력한다.
empty: 큐가 비어있으면 1, 아니면 0을 출력한다.
front: 큐의 가장 앞에 있는 정수를 출력한다. 만약 큐에 들어있는 정수가 없는 경우에는 -1을 출력한다.
back: 큐의 가장 뒤에 있는 정수를 출력한다. 만약 큐에 들어있는 정수가 없는 경우에는 -1을 출력한다.

const filePath = process.platform === "linux" ? "/dev/stdin" : "./input.txt";

const input = require("fs").readFileSync(filePath).toString().trim().split("\n");
const N = input.shift();

class Node {
  constructor(value) {
    this.value = value;
    this.prev = null;
    this.next = null;
  }
}

class Queue {
  constructor(value) {
    this.head = null;
    this.tail = null;
    this.size = 0;
  }

  push(value) {
    const node = new Node(value);

    if (!this.head) {
      this.head = node;
    } else {
      this.tail.next = node;
    }

    this.tail = node;
    this.size++;
  }

  pop() {
    if (this.size > 2) {
      const value = this.head.value;
      const newHead = this.head.next;
      this.head = newHead;
      newHead.prev = this.tail;
      this.tail.next = this.head;
      this.size--;
      return value;
    } else if (this.size === 2) {
      const value = this.head.value;
      this.head = this.tail;
      this.tail.prev = this.tail;
      this.tail.next = this.tail;
      this.size--;
      return value;
    } else if (this.size === 1) {
      const value = this.head.value;
      this.head = null;
      this.tail = null;
      this.size--;
      return value;
    } else {
      return -1;
    }
  }

  getSize() {
    return this.size;
  }

  empty() {
    return this.size ? 0 : 1;
  }

  getFront() {
    return this.head ? this.head.value : -1;
  }

  getBack() {
    return this.tail ? this.tail.value : -1;
  }
}

const queue = new Queue();

let answer = "";

for (let i = 0; i < N; i++) {
  const [command, value] = input[i].split(" ");

  switch (command) {
    case "push":
      queue.push(value);
      break;
    case "pop":
      answer += `${queue.pop()}\n`;
      break;
    case "size":
      answer += `${queue.getSize()}\n`;
      break;
    case "empty":
      answer += `${queue.empty()}\n`;
      break;
    case "front":
      answer += `${queue.getFront()}\n`;
      break;
    case "back":
      answer += `${queue.getBack()}\n`;
      break;
    default:
      break;
  }
}

console.log(answer.trim());

 

문제풀이(2) - 리팩토링

1. pop 메서드 개선: pop 메서드에서 큐의 크기에 상관없이 항상 첫 번째 노드를 제거하고 크기를 감소시키도록 변경하고, 마지막 노드와의 연결 상태를 확인하고 조정하는 부분도 개선진행.
실행시간 - 2724ms -> 2400ms

const filePath = process.platform === "linux" ? "/dev/stdin" : "./input.txt";

const input = require("fs").readFileSync(filePath).toString().trim().split("\n");
const N = input.shift();

class Node {
  constructor(value) {
    this.value = value;
    this.prev = null;
    this.next = null;
  }
}

class Queue {
  constructor(value) {
    this.head = null;
    this.tail = null;
    this.size = 0;
  }

  push(value) {
    const node = new Node(value);

    if (!this.head) {
      this.head = node;
    } else {
      this.tail.next = node;
    }

    this.tail = node;
    this.size++;
  }

  pop() {
    if (this.size === 0) {
      return -1;
    }

    const value = this.head.value;
    this.head = this.head.next;

    if (this.head) {
      this.head.prev = null;
    } else {
      this.tail = null;
    }

    this.size--;

    return value;
  }

  getSize() {
    return this.size;
  }

  empty() {
    return this.size ? 0 : 1;
  }

  getFront() {
    return this.head ? this.head.value : -1;
  }

  getBack() {
    return this.tail ? this.tail.value : -1;
  }
}

const queue = new Queue();

let answer = "";

for (let i = 0; i < N; i++) {
  const [command, value] = input[i].split(" ");

  switch (command) {
    case "push":
      queue.push(value);
      break;
    case "pop":
      answer += `${queue.pop()}\n`;
      break;
    case "size":
      answer += `${queue.getSize()}\n`;
      break;
    case "empty":
      answer += `${queue.empty()}\n`;
      break;
    case "front":
      answer += `${queue.getFront()}\n`;
      break;
    case "back":
      answer += `${queue.getBack()}\n`;
      break;
    default:
      break;
  }
}

console.log(answer.trim());

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

 

1620번: 나는야 포켓몬 마스터 이다솜

첫째 줄에는 도감에 수록되어 있는 포켓몬의 개수 N이랑 내가 맞춰야 하는 문제의 개수 M이 주어져. N과 M은 1보다 크거나 같고, 100,000보다 작거나 같은 자연수인데, 자연수가 뭔지는 알지? 모르면

www.acmicpc.net

입력

첫째 줄에는 도감에 수록되어 있는 포켓몬의 개수 N이랑 내가 맞춰야 하는 문제의 개수 M이 주어져. N과 M은 1보다 크거나 같고, 100,000보다 작거나 같은 자연수인데, 자연수가 뭔지는 알지? 모르면 물어봐도 괜찮아. 나는 언제든지 질문에 답해줄 준비가 되어있어.

둘째 줄부터 N개의 줄에 포켓몬의 번호가 1번인 포켓몬부터 N번에 해당하는 포켓몬까지 한 줄에 하나씩 입력으로 들어와. 포켓몬의 이름은 모두 영어로만 이루어져있고, 또, 음... 첫 글자만 대문자이고, 나머지 문자는 소문자로만 이루어져 있어. 아참! 일부 포켓몬은 마지막 문자만 대문자일 수도 있어. 포켓몬 이름의 최대 길이는 20, 최소 길이는 2야. 그 다음 줄부터 총 M개의 줄에 내가 맞춰야하는 문제가 입력으로 들어와. 문제가 알파벳으로만 들어오면 포켓몬 번호를 말해야 하고, 숫자로만 들어오면, 포켓몬 번호에 해당하는 문자를 출력해야해. 입력으로 들어오는 숫자는 반드시 1보다 크거나 같고, N보다 작거나 같고, 입력으로 들어오는 문자는 반드시 도감에 있는 포켓몬의 이름만 주어져. 그럼 화이팅!!!

출력

첫째 줄부터 차례대로 M개의 줄에 각각의 문제에 대한 답을 말해줬으면 좋겠어!!!. 입력으로 숫자가 들어왔다면 그 숫자에 해당하는 포켓몬의 이름을, 문자가 들어왔으면 그 포켓몬의 이름에 해당하는 번호를 출력하면 돼. 그럼 땡큐~

이게 오박사님이 나에게 새로 주시려고 하는 도감이야. 너무 가지고 싶다ㅠㅜ. 꼭 만점을 받아줬으면 좋겠어!! 파이팅!!!

예제 입력 1 복사

26 5
Bulbasaur
Ivysaur
Venusaur
Charmander
Charmeleon
Charizard
Squirtle
Wartortle
Blastoise
Caterpie
Metapod
Butterfree
Weedle
Kakuna
Beedrill
Pidgey
Pidgeotto
Pidgeot
Rattata
Raticate
Spearow
Fearow
Ekans
Arbok
Pikachu
Raichu
25
Raichu
3
Pidgey
Kakuna

예제 출력 1 복사

Pikachu
26
Venusaur
16
14

 

먼가 문제부터 입력, 출력까지 딱딱한 분위기로 출제 되지 않는 문제는 처음보기 때문에 낯설었던 문제이다.

문제풀이(1) - 실패(시간초과)

포켓몬 도감과 질문 목록 배열을 두개를 생성한뒤 질문 목록의 포켓몬, 번호를 포켓몬 도감에서 찾는다.

const filePath = process.platform === "linux" ? "/dev/stdin" : "./input.txt";

const input = require("fs").readFileSync(filePath).toString().trim().split("\n");
const [N, M] = input.shift().split(" ").map(Number);

const pokemonCollection = input.slice(0, N);
const questionArr = input.slice(N);

const answer = [];

questionArr.forEach((question) => {
  const convertQuestion = parseInt(question);

  if (!isNaN(convertQuestion)) {
    answer.push(pokemonCollection[convertQuestion - 1]);
  } else {
    answer.push(pokemonCollection.indexOf(question) + 1);
  }
});

console.log(answer.join("\n"));

 

문제풀이(2)

문제풀이(1)은 indexOf를 사용할 경우 모든 배열을 순회하기 때문에 시간초과가 나온 것 같다.
indexOf를 제거하고 포켓몬 도감을 map에 추가하여 바로 확인할 수 있도록 한다.

const filePath = process.platform === "linux" ? "/dev/stdin" : "./input.txt";

const input = require("fs").readFileSync(filePath).toString().trim().split("\n");
const [N, M] = input.shift().split(" ").map(Number);

const pokemonCollectionMap = new Map();

const pokemonCollection = input.slice(0, N);
const questionArr = input.slice(N);

const answer = [];

for (let i = 0; i < pokemonCollection.length; i++) {
  pokemonCollectionMap.set(pokemonCollection[i], i + 1);
}

questionArr.forEach((question) => {
  const convertQuestion = parseInt(question);

  if (!isNaN(convertQuestion)) {
    answer.push(pokemonCollection[convertQuestion - 1]);
  } else {
    answer.push(pokemonCollectionMap.get(question));
  }
});

console.log(answer.join("\n"));

 

문제풀이(3) - 리팩토링

1. Map에 할당하는 반복 루프를 for -> forEach로 변경함에 따라 실행시간 단축

const filePath = process.platform === "linux" ? "/dev/stdin" : "./input.txt";

const input = require("fs").readFileSync(filePath).toString().trim().split("\n");
const [N, M] = input.shift().split(" ").map(Number);

const pokemonCollectionMap = new Map();

const pokemonCollection = input.slice(0, N);
const questionArr = input.slice(N);

const answer = [];

pokemonCollection.forEach((pokemon, index) => {
  pokemonCollectionMap.set(pokemon, index + 1);
});

questionArr.forEach((question) => {
  const convertQuestion = parseInt(question);

  if (!isNaN(convertQuestion)) {
    answer.push(pokemonCollection[convertQuestion - 1]);
  } else {
    answer.push(pokemonCollectionMap.get(question));
  }
});

console.log(answer.join("\n"));

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

 

4949번: 균형잡힌 세상

각 문자열은 마지막 글자를 제외하고 영문 알파벳, 공백, 소괄호("( )"), 대괄호("[ ]")로 이루어져 있으며, 온점(".")으로 끝나고, 길이는 100글자보다 작거나 같다. 입력의 종료조건으로 맨 마지막에

www.acmicpc.net

문제

세계는 균형이 잘 잡혀있어야 한다. 양과 음, 빛과 어둠 그리고 왼쪽 괄호와 오른쪽 괄호처럼 말이다.

정민이의 임무는 어떤 문자열이 주어졌을 때, 괄호들의 균형이 잘 맞춰져 있는지 판단하는 프로그램을 짜는 것이다.

문자열에 포함되는 괄호는 소괄호("()") 와 대괄호("[]")로 2종류이고, 문자열이 균형을 이루는 조건은 아래와 같다.

  • 모든 왼쪽 소괄호("(")는 오른쪽 소괄호(")")와만 짝을 이뤄야 한다.
  • 모든 왼쪽 대괄호("[")는 오른쪽 대괄호("]")와만 짝을 이뤄야 한다.
  • 모든 오른쪽 괄호들은 자신과 짝을 이룰 수 있는 왼쪽 괄호가 존재한다.
  • 모든 괄호들의 짝은 1:1 매칭만 가능하다. 즉, 괄호 하나가 둘 이상의 괄호와 짝지어지지 않는다.
  • 짝을 이루는 두 괄호가 있을 때, 그 사이에 있는 문자열도 균형이 잡혀야 한다.

정민이를 도와 문자열이 주어졌을 때 균형잡힌 문자열인지 아닌지를 판단해보자.

입력

각 문자열은 마지막 글자를 제외하고 영문 알파벳, 공백, 소괄호("( )"), 대괄호("[ ]")로 이루어져 있으며, 온점(".")으로 끝나고, 길이는 100글자보다 작거나 같다.

입력의 종료조건으로 맨 마지막에 온점 하나(".")가 들어온다.

출력

각 줄마다 해당 문자열이 균형을 이루고 있으면 "yes"를, 아니면 "no"를 출력한다.

예제 입력 1 복사

So when I die (the [first] I will see in (heaven) is a score list).
[ first in ] ( first out ).
Half Moon tonight (At least it is better than no Moon at all].
A rope may form )( a trail in a maze.
Help( I[m being held prisoner in a fortune cookie factory)].
([ (([( [ ] ) ( ) (( ))] )) ]).
 .
.

예제 출력 1 복사

yes
yes
no
no
no
yes
yes

 

문제풀이(1)

올바른 괄호 찾는 문제이다.
마지막은 온점으로 끝이난다.
1. 열리는 괄호를 배열에 쌓고, 닫히는 괄호가 나올때 열리는 괄호의 짝과 같은지 확인한다.

const filePath = process.platform === "linux" ? "/dev/stdin" : "./input.txt";

const input = require("fs").readFileSync(filePath).toString().trim().split("\n");

// 올바른 괄호 체크 함수
const bracketsCheck = (arr) => {
  const result = [];

  for (let i = 0; i < arr.length; i++) {
    const text = arr[i];
    const openBracketArr = [];
    let isCheck = true;

    // 마지막에 .이 나올경우 종료
    if (text === ".") break;

    for (let j = 0; j < text.length; j++) {
      let str = text[j];
      if (["(", "["].includes(str)) {
        openBracketArr.push(str);
      } else if (str === ")") {
        if (openBracketArr.at(-1) === "(") {
          openBracketArr.pop();
        } else {
          isCheck = false;
          break;
        }
      } else if (str === "]") {
        if (openBracketArr.at(-1) === "[") {
          openBracketArr.pop();
        } else {
          isCheck = false;
          break;
        }
      } else if (str === ".") {
        break;
      }
    }

    if (openBracketArr.length || !isCheck) {
      result.push("no");
    } else {
      result.push("yes");
    }
  }

  return result;
};

console.log(bracketsCheck(input).join("\n"));

 

문제풀이(2)

1. 가독성을 위해 함수명 변경
2. 각 배열 요소에 대해 동일한 로직을 적용하기 때문에 for 대신 map 메서드를 사용.
3. 중첩된 for 제거
4. pop 한 결과를 변수에 할당하여 가독성 향상
5. 각 문자열을 처리하는 경우 .은 필요없음. (만일 문자열 내 .이 많다면 해당 부분 추가)
6. 괄호 비교하는 if 문 수정

const filePath = process.platform === "linux" ? "/dev/stdin" : "./input.txt";
const input = require("fs").readFileSync(filePath).toString().trim().split("\n");

const checkBrackets = (arr) => {
  const result = arr.map((input) => {
    if (input === ".") return;
    const stack = [];
    for (const char of input) {
      if (char === "(" || char === "[") {
        stack.push(char);
      } else if (char === ")" || char === "]") {
        if (stack.length === 0) return "no";
        const lastBracket = stack.pop();
        if ((lastBracket === "(" && char !== ")") || (lastBracket === "[" && char !== "]")) {
          return "no";
        }
      }
    }
    return stack.length > 0 ? "no" : "yes";
  });

  return result;
};

console.log(checkBrackets(input).join("\n"));

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

 

1764번: 듣보잡

첫째 줄에 듣도 못한 사람의 수 N, 보도 못한 사람의 수 M이 주어진다. 이어서 둘째 줄부터 N개의 줄에 걸쳐 듣도 못한 사람의 이름과, N+2째 줄부터 보도 못한 사람의 이름이 순서대로 주어진다.

www.acmicpc.net

문제

김진영이 듣도 못한 사람의 명단과, 보도 못한 사람의 명단이 주어질 때, 듣도 보도 못한 사람의 명단을 구하는 프로그램을 작성하시오.

입력

첫째 줄에 듣도 못한 사람의 수 N, 보도 못한 사람의 수 M이 주어진다. 이어서 둘째 줄부터 N개의 줄에 걸쳐 듣도 못한 사람의 이름과, N+2째 줄부터 보도 못한 사람의 이름이 순서대로 주어진다. 이름은 띄어쓰기 없이 알파벳 소문자로만 이루어지며, 그 길이는 20 이하이다. N, M은 500,000 이하의 자연수이다.

듣도 못한 사람의 명단에는 중복되는 이름이 없으며, 보도 못한 사람의 명단도 마찬가지이다.

출력

듣보잡의 수와 그 명단을 사전순으로 출력한다.

예제 입력 1 복사

3 4
ohhenrie
charlie
baesangwook
obama
baesangwook
ohhenrie
clinton

예제 출력 1 복사

2
baesangwook
ohhenrie

 

문제풀이(1)

N = 듣도 못한 사람의 수, M = 보도 못한 사람의 수
듣도 못한 사람과 보도 못한 사람들의 이름에는 중복이 없다.
이진탐색을 사용해서 탐색한다.

const filePath = process.platform === "linux" ? "/dev/stdin" : "./input.txt";

const input = require("fs").readFileSync(filePath).toString().trim().split("\n");
const [N, M] = input.shift().split(" ").map(Number);

const peopleN = input.slice(0, N).sort();
const peopleM = input.slice(N).sort();

let answer = [];

const binarySearch = (arr, target) => {
  let low = 0;
  let high = arr.length - 1;

  while (low <= high) {
    const mid = Math.floor((low + high) / 2);

    // 중간값이 타겟과 일치하는 경우
    if (arr[mid] === target) {
      return target;
    }

    // 중간값이 타겟보다 작으면 오른쪽 부분 탐색
    if (arr[mid] < target) {
      low = mid + 1;
    } else if (arr[mid] > target) {
      // 중간값이 타겟보다 크면 왼쪽 부분 탐색
      high = mid - 1;
    } else {
      return target;
    }
  }

  return false;
};

const [longArr, shortArr] = N > M ? [peopleN, peopleM] : [peopleM, peopleN];

shortArr.forEach((name) => {
  let peopleNM = binarySearch(longArr, name);
  if (peopleNM) {
    answer.push(peopleNM);
  }
});

console.log(`${answer.length}\n${answer.join("\n")}`);

 

문제풀이(2)

이진탐색을 사용하지 않은 풀이
이진탐색을 했을경우보다 메모리는 많이 사용하지만 실행시간은 줄었다.
문제풀이(1)-이진탐색o : 메모리 23056kb, 실행시간 364ms
문제풀이(2)-이진탐색x : 메모리 30660kb, 실행시간 256ms

const filePath = process.platform === "linux" ? "/dev/stdin" : "./input.txt";

const input = require("fs").readFileSync(filePath).toString().trim().split("\n");
const [N, M] = input.shift().split(" ").map(Number);

const map = new Map();
const answer = [];

for (let i = 0; i < input.length; i++) {
  if (map.has(input[i])) {
    answer.push(input[i]);
  } else {
    map.set(input[i]);
  }
}

console.log(`${answer.length}\n${answer.sort().join("\n")}`);

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

 

1026번: 보물

첫째 줄에 N이 주어진다. 둘째 줄에는 A에 있는 N개의 수가 순서대로 주어지고, 셋째 줄에는 B에 있는 수가 순서대로 주어진다. N은 50보다 작거나 같은 자연수이고, A와 B의 각 원소는 100보다 작거

www.acmicpc.net

문제

옛날 옛적에 수학이 항상 큰 골칫거리였던 나라가 있었다. 이 나라의 국왕 김지민은 다음과 같은 문제를 내고 큰 상금을 걸었다.

길이가 N인 정수 배열 A와 B가 있다. 다음과 같이 함수 S를 정의하자.

S = A[0] × B[0] + ... + A[N-1] × B[N-1]

S의 값을 가장 작게 만들기 위해 A의 수를 재배열하자. 단, B에 있는 수는 재배열하면 안 된다.

S의 최솟값을 출력하는 프로그램을 작성하시오.

입력

첫째 줄에 N이 주어진다. 둘째 줄에는 A에 있는 N개의 수가 순서대로 주어지고, 셋째 줄에는 B에 있는 수가 순서대로 주어진다. N은 50보다 작거나 같은 자연수이고, A와 B의 각 원소는 100보다 작거나 같은 음이 아닌 정수이다.

출력

첫째 줄에 S의 최솟값을 출력한다.

예제 입력 1 복사

5
1 1 1 6 0
2 7 8 3 1

예제 출력 1 복사

18

 

문제풀이(1)

A[0]xB[0]+...+A[N-1]xB[N-1] 일 경우에 총합의 값이 작은 방법을 찾는 문제다.
A는 재배열할 수 있고, B는 재배열할 수 없다.
A의 작은값과 B의 큰값을 매치하는 방식으로 하면 가장 작은 총합이 나올 것이다.
1. A를 오름차순으로 정렬한다.
2. B의 가장 큰값을 찾고 계산한뒤 큰값의 인덱스를 제거한다.

const filePath = process.platform === "linux" ? "/dev/stdin" : "./input.txt";

const input = require("fs").readFileSync(filePath).toString().trim().split("\n");
const N = Number(input.shift());
const A = input[0]
  .split(" ")
  .map(Number)
  .sort((a, b) => a - b); // 오름차순 정렬
const B = input[1].split(" ").map(Number);

let answer = 0;

for (let i = 0; i < N; i++) {
  // B배열의 가장 큰값
  let maxNumB = Math.max(...B);
  // B배열의 가장 큰값의 인덱스 번호
  let maxNumBIdx = B.indexOf(maxNumB);
  // B배열의 가장 큰값 제거
  B.splice(maxNumBIdx, 1);

  let multi = A[i] * maxNumB;
  answer += multi;
}

console.log(answer);

 

문제풀이(2)

문제풀이(1)와 같이 풀어봤을 때 사실 B.splice를 한다는 것은 재배열하는 것과 같은데 풀렸기 때문에
sort 메소드를 사용해서 풀어봤는데 통과가 되었다.
B의 배열을 재배열했는지 여부를 판단하는 기준이 없는 것 같다.

const filePath = process.platform === "linux" ? "/dev/stdin" : "./input.txt";

const input = require("fs").readFileSync(filePath).toString().trim().split("\n");
const N = Number(input.shift());
const A = input[0]
  .split(" ")
  .map(Number)
  .sort((a, b) => a - b); // 오름차순 정렬
const B = input[1]
  .split(" ")
  .map(Number)
  .sort((a, b) => b - a);

let answer = 0;

A.forEach((numA, idx) => {
  answer += numA * B[idx];
});

console.log(answer);

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

 

10816번: 숫자 카드 2

첫째 줄에 상근이가 가지고 있는 숫자 카드의 개수 N(1 ≤ N ≤ 500,000)이 주어진다. 둘째 줄에는 숫자 카드에 적혀있는 정수가 주어진다. 숫자 카드에 적혀있는 수는 -10,000,000보다 크거나 같고, 10,0

www.acmicpc.net

문제

숫자 카드는 정수 하나가 적혀져 있는 카드이다. 상근이는 숫자 카드 N개를 가지고 있다. 정수 M개가 주어졌을 때, 이 수가 적혀있는 숫자 카드를 상근이가 몇 개 가지고 있는지 구하는 프로그램을 작성하시오.

입력

첫째 줄에 상근이가 가지고 있는 숫자 카드의 개수 N(1 ≤ N ≤ 500,000)이 주어진다. 둘째 줄에는 숫자 카드에 적혀있는 정수가 주어진다. 숫자 카드에 적혀있는 수는 -10,000,000보다 크거나 같고, 10,000,000보다 작거나 같다.

셋째 줄에는 M(1 ≤ M ≤ 500,000)이 주어진다. 넷째 줄에는 상근이가 몇 개 가지고 있는 숫자 카드인지 구해야 할 M개의 정수가 주어지며, 이 수는 공백으로 구분되어져 있다. 이 수도 -10,000,000보다 크거나 같고, 10,000,000보다 작거나 같다.

출력

첫째 줄에 입력으로 주어진 M개의 수에 대해서, 각 수가 적힌 숫자 카드를 상근이가 몇 개 가지고 있는지를 공백으로 구분해 출력한다.

예제 입력 1 복사

10
6 3 2 10 10 10 -10 -10 7 3
8
10 9 -5 2 3 4 5 -10

예제 출력 1 복사

3 0 0 1 2 0 0 2

 

문제풀이(1) - 실패

1920번 수 찾기와 비슷한 문제이다.
B배열에서 값들을 순회하며 해당 값이 A배열에 몇개 가지고 있는지 판별하면 되는 문제이다.

const filePath = process.platform === "linux" ? "/dev/stdin" : "./input.txt";

const input = require("fs").readFileSync(filePath).toString().trim().split("\n");
const [N, A, M, B] = input.map((line) => line.split(" ").map(Number));

const answer = [];

B.forEach((value) => {
  let count = A.filter((num) => num === value).length;
  answer.push(count);
});

console.log(answer.join(" ").trim());

 

문제풀이(2)

문제풀이(1)의 실패는 예견된 일이었다.
10,000,000보다 크거나 같고, 10,000,000보다 작거나 같다. 라는 조건문이 있었기 때문에 시간복접도 문제였다.
A배열을 1회 순회하며 객체에 count하는 방식으로 해보기로했다.

const filePath = process.platform === "linux" ? "/dev/stdin" : "./input.txt";

const input = require("fs").readFileSync(filePath).toString().trim().split("\n");
const [N, A, M, B] = input.map((line) => line.split(" ").map(Number));

let answer = "";
const map = new Map();

for (num of A) {
  if (map.has(num)) {
    map.set(num, map.get(num) + 1);
  } else {
    map.set(num, 1);
  }
}

for (num of B) {
  if (map.get(num)) {
    answer += `${map.get(num)} `;
  } else {
    answer += "0 ";
  }
}

console.log(answer.trim());

 

+ Recent posts