알고리즘/코테

[백준 9997] 폰트

kiwiiiv 2022. 10. 27. 15:06

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

 

9997번: 폰트

첫째 줄에 단어의 개수 N (1 ≤ N ≤ 25)가 주어진다. 다음 N개 줄에는 사전에 포함되어있는 단어가 주어진다. 단어의 길이는 100을 넘지 않으며, 중복되는 단어는 주어지지 않는다.

www.acmicpc.net

 

테스트 문장에는 알파벳 소문자 26개가 모두 포함되어 있어야 한다.

-> 문장(또는 단어) 어떤 알파벳이 포함되어 있는지 여부를 판단하자!!

 

 

=> 비트마스킹 도입

집합 원소의 개수가 적을 때, 비트마스크를 통한 집합의 원소 삭제, 추가, 집합끼리의 계산 등의 연산을 효율적으로 수행할 수 있음

알파벳 소문자 26개만을 원소로 가지므로, 이에 적합

 

- 비트마스크 연산

https://loosie.tistory.com/238

 

[알고리즘] 비트(Bit)와 비트마스크(BitMask) 정리 (Java)

비트(bit) 비트(binary digit)는 데이터를 나타내는 최소 단위로 이진수의 한자라인 0 또는 1의 값을 가진다. 부호 없는 N비트 정수형 변수는 N자리의 이진수로 나타낼 수 있다. 이때 비트가 표현하는

loosie.tistory.com

 

 

문자열 abcd를 1111(2)=15(10)

문자열 e를 10000(2)=16(10)

이와 같이 변환하면

 

문장 "abcd e" (문자열 abcd, e의 합집합)

1111 | 10000 = 11111

이처럼 연산할 수 있다(시간복잡도 O(1))

 

위의 방식을 통하여 어떤 문장에 소문자 알파벳 모두가 포함되어있는지 여부를 판단할 수 있음

 

 

 

 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;

public class Main {
	public static final int MAX_SENTENCE = (1 << 26) - 1;
	public static int countOfsentences = 0;

	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		int countOfWords = Integer.valueOf(br.readLine());
		ArrayList<Word> words = new ArrayList<>();
		for (int i = 0; i < countOfWords; i++) {
			String input = br.readLine();
			words.add(new Word(input, convertToBits(input)));
		}
		countViaDfs(words, 0, 0);
		System.out.println(countOfsentences);
	}

	private static void countViaDfs(ArrayList<Word> words, int currSentence, int idx) {
		if (idx == words.size())
			return;
		//포함x
		countViaDfs(words, currSentence, idx + 1);

		//포함o
		int newSentence = currSentence | words.get(idx).converted;
		if (newSentence == MAX_SENTENCE) {
			countOfsentences += 1 << (words.size() - (idx + 1));
		} else {
			countViaDfs(words, newSentence, idx + 1);
		}
	}

	private static int convertToBits(String s) {
		int bitsSentence = 0;
		for (int i = 0; i < s.length(); i++) {
			char c = s.charAt(i);
			bitsSentence |= 1 << (c - 'a');
		}
		return bitsSentence;
	}
}

class Word {
	String origin;
	int converted;

	public Word(String origin, int converted) {
		this.origin = origin;
		this.converted = converted;
	}
}