GCJ2011 Qualification Round B Magicka
GCJ当時,twitterでGCJの問題マギカらしいよ!というのが流れていたのを思い出した.
http://code.google.com/codejam/contest/dashboard?c=975485#s=p1
問題
- まどマギとは関係ない(ぉ
- 8つの基本となるエレメントがあり,それぞれ1文字で{Q, W, E, R, A, S, D, F}
- あるエレメントを呼び出すと,エレメントリストに付け加えられる
- たとえば,Wを呼び出した後にAを呼び出すと,エレメントリストは[W, A]になる
- 基本ではない他の18文字は基本エレメントのペアで指定される.たとえばQとFでTになる.つまり,[A, Q, F]や[A, F, Q]は[A, T]になる.
- 相反する基本エレメントのペアが存在する.相反するエレメントが呼び出され,他のエレメントと結合することがないとき,そのリストの全要素がクリアされる.
- 入力データは(C, D, N)となっている.Cは3文字で表され,2つの基本エレメントから別のエレメントをつくることを表す.Dは2文字で表され相反するエレメントとなっている.Nは順番に呼び出されるエレメントである.
- 最終的にエレメントのリストはどのようになるか?
プログラム
import java.util.*; import java.io.*; public class Qualifer_02_2011 { public void solve() throws Exception { Scanner sc = new Scanner(new FileReader("./input/B-large-practice.in")); PrintWriter pw = new PrintWriter(new FileWriter("./output/Q02_2011output.txt")); int caseCnt = sc.nextInt(); for (int caseNum = 0; caseNum < caseCnt; caseNum++) { pw.print("Case #" + (caseNum + 1) + ": "); //combinationを配列に int combCnt = sc.nextInt(); boolean[][] isComb = new boolean[26][26]; char[][] comb = new char[26][26]; for (int i=0; i < combCnt; i++) { String s = sc.next(); isComb[s.charAt(0) - 'A'][s.charAt(1) - 'A'] = true;//配列の何番目がcombか? isComb[s.charAt(1) - 'A'][s.charAt(0) - 'A'] = true; comb[s.charAt(0) - 'A'][s.charAt(1) - 'A'] = s.charAt(2);//できあがる文字列を配列に comb[s.charAt(1) - 'A'][s.charAt(0) - 'A'] = s.charAt(2); } //opposedを配列に int oppCnt = sc.nextInt(); boolean[][] isOpp = new boolean[26][26]; for (int i=0; i < oppCnt; i++) { String s = sc.next(); isOpp[s.charAt(0) - 'A'][s.charAt(1) - 'A'] = true; isOpp[s.charAt(1) - 'A'][s.charAt(0) - 'A'] = true; } int N = sc.nextInt(); String s = sc.next(); List<Character> cur = new ArrayList<Character>(); for (char c : s.toCharArray()) { cur.add(c); if (cur.size() > 1) { char p = cur.get(cur.size() - 2); if (isComb[p-'A'][c-'A']) { cur.remove(cur.size() - 1); cur.remove(cur.size() - 1); cur.add(comb[p-'A'][c-'A']); } else { for (int i=0; i < cur.size() - 1; i++) { char x = cur.get(i); if (isOpp[x-'A'][c-'A']) { cur = new ArrayList<Character>(); break; } } } } } pw.print("["); for (int i=0; i < cur.size(); i++) { if (i >= 1) pw.print(", "); pw.print(cur.get(i)); } pw.println("]"); } pw.flush(); pw.close(); sc.close(); } public static void main(String[] args) throws Exception { new Qualifer_02_2011().solve(); } }
基本的には前から順に,combinationになる組合せをチェック,その場合は新規文字に変換,次にopposedになる組合せをチェックし,リストを初期化するのいう処理を行えばいいわけですね.ま,いろんな方の解答を参考にしたわけですが(汗)