
https://www.acmicpc.net/problem/3986
우선은 좋은 단어가 무엇인지를 제대로 정의하고 시작해야한다. (이거부터 이해가 안됐음ㅜㅜ)
단어를 두고 A는 A끼리, B는 B끼리 쌍을 지어 곡선을 그린다.

예를 들어, 이런 경우에는 좋은 단어가 될 수 없다. 각각의 곡선이 교차하였기 때문 !!
그렇다면 좋은 단어는 어떤 경우인가?

바로 이런 경우이다. 각각의 곡선이 교차하지 않고 쌍을 이룰 수 있는 형태!
백준 사이트 내에 알고리즘 분류가 자료구조, 스택인 것을 확인하고 문제를 더 풀어나갔다.
우선은 각각의 단어가 좋은 단어인지 확인하는 것을 반복하는 것으로 문제를 작게 나누었다.
각각의 단어가 좋은 단어인가?를 판단하는 함수를 먼저 구현하고, 이걸 단어의 수만큼 반복하면 된다.
스택에 값을 차례로 push하다가 마지막 두개의 값이 AA 혹은 BB가 되면 스택에서 값을 두번 pop하는 방법을 생각했다.
function find(string) {
let stack = [];
for (let i = 0; i < string.length; i++) {
stack.push(string[i]);
if (
stack[stack.length - 2] + stack[stack.length - 1] == "AA" ||
stack[stack.length - 2] + stack[stack.length - 1] == "BB"
) {
stack.pop();
stack.pop();
}
}
}
하지만 이렇게 했을 때에는 교차하지 않고 쌍을 이루는 경우는 찾을 수 있지만, 좋은 단어의 개수는 찾을 수 없다.
좋은 단어이기 위해서는 문자열 내의 모든 값이 쌍을 이루되, 교차하지 않아야한다.
교차하지 않고 쌍을 이루는 경우에는 값을 pop하기 때문에, 좋은 단어라면 모든 반복이 끝난 후에 스택은 비어있을 것이다.
return stack.length == 0 ? true : false;
이렇게 리턴값을 추가해서 좋은 단어인 경우에 true(1)를 리턴하도록 했다.
for (let i = 0; i < count; i++) {
cnt += find(strings[i]);
}
console.log(cnt);
함수의 호출부에서 단어의 개수만큼 반복하고, 리턴값을 cnt 변수에 더하여 좋은 단어의 개수를 센다.
let cnt = 0;
function find(string) {
let stack = [];
for (let i = 0; i < string.length; i++) {
stack.push(string[i]);
if (
stack[stack.length - 2] + stack[stack.length - 1] == "AA" ||
stack[stack.length - 2] + stack[stack.length - 1] == "BB"
) {
stack.pop();
stack.pop();
}
}
// console.log(stack);
return stack.length == 0 ? true : false;
}
// =====입출력=====
const readline = require("readline");
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
let input = [];
rl.on("line", (line) => {
input.push(line);
if (input.length === parseInt(input[0]) + 1) {
rl.close();
}
}).on("close", () => {
const count = parseInt(input[0]);
const strings = input.slice(1, count + 1);
for (let i = 0; i < count; i++) {
cnt += find(strings[i]);
}
console.log(cnt);
});
