文系プログラマーのプログラミング備忘録

Java、競プロ、数学などについて書いてます

怪文書 [AtCoder Regular Contest 071 C]

atcoder.jp


全ての文字列に共通する文字を取り出して、辞書順最小の文字列を合成する問題です。


解説はコードの中に埋め込んだので、そちらをご覧ください。
方針としては、


・1番目の文字列に含まれる文字を共通文字とする
・2番目以降の文字列について、その共通文字と比較していく
 →1番目の文字列に "a" が2個あったのに、2番目の文字列に1個しかなければ、1個に更新するという具合
・最終的に求まった共通文字をリストに詰めて昇順にソート、出力する


といった流れになっています。


import java.util.*;

void solve () {

	//入力
	int n = nextInt();
	int[] alphabet = new int[26];

	//最初の文字列に登場する英小文字の数を数える
	String s = next();
	for (int i=0; i<s.length(); i++) {
		alphabet[s.charAt(i)-97]++;
	}

	//残りの文字列を見ていく
	for (int i=0; i<n-1; i++) {

		s = next();
		int[] temp = new int[26];

		//文字列iに登場する英小文字の数を数える
		for (int j=0; j<s.length(); j++) {
			temp[s.charAt(j)-97]++;
		}

		//最初の文字列と比較して、登場回数が少ないほうを採用する
		//以後、次々に更新していく
		for (int j=0; j<26; j++) {
			alphabet[j] = Math.min(alphabet[j], temp[j]);
		}

	}

	//登場回数が1以上の文字列(全ての文字列に登場した英小文字)のみListに詰める
	ArrayList<Character> list = new ArrayList<>();
	for (int i=0; i<26; i++) {
		if (alphabet[i] > 0) {
			for (int j=0; j<alphabet[i]; j++) {
				list.add((char)(i+97));
			}
		}
	}

	//ソートして辞書順最小にする
	Collections.sort(list);

	//出力して終了
	for (int i=0; i<list.size(); i++) {
		out.print(list.get(i));
	}
	out.println();

}


少し難しい200点問題かなと思ったら300点問題でした。300点問題にしては素直で優しいほうではないでしょうか。