SRM454 div2

Tags: ,
  2009/12/08 00:02

眠いけど、一応出た。

Easy MinimalDifference

問題文を忠実にコードに起こすだけ。
速攻テスト通ったー!と思って油断してたら、for文の範囲ミスってて撃墜されたorz
2文字切っただけでシステム通った。

0.0

Midium WordsGame

文字がN個xN個の格子状に配置されていて、
与えられた長さNの文字列に一致(*1)するようにswap(*2)を繰り返す。
*1 一致は「上から下」か「左から右」のみ。斜めとかなし。
*2 swapは列同士か行同士しかできない。文字単位ではNG
もし完成すれば最小コストを返せという問題。

N <= 50なので、単純な探索は無理。

ただ、swapできると言っても、列か行単位のみ。
ということは、もし「左から右」の行で完成する場合は、列swapのみ。
逆に、「上から下」の列で完成する場合は、行swapしかしないことになる。

なので、列か行単位でみてけばよい。
2N個の長さNの文字配列を与えられた長さNの文字列に近づける。
ずいぶん簡単になった。

public class WordsGame {
	String[] strings;
	int cost = Integer.MAX_VALUE;

	public int minimumSwaps(String[] grid, String word) {
		strings = new String[grid.length * 2];

		for (int i = 0; i < grid.length; i++) {
			strings[i] = grid[i];
		}
		for (int i = 0; i < grid.length; i++) {
			StringBuilder sb = new StringBuilder();
			for (int j = 0; j < grid.length; j++) {
				sb.append(grid[j].charAt(i));
			}
			strings[i + grid.length] = sb.toString();
		}

		for (int i = 0; i < strings.length; i++) {
			solve(word, strings[i], 0, 0);
		}

		return (this.cost == Integer.MAX_VALUE) ? -1 : this.cost;
	}

	public void solve(String s, String t, int index, int cost) {
//		System.out.println("#solve index="+index+", cost="+cost+", src="+s+", target="+t);

		char[] src = s.toCharArray();
		char[] target = t.toCharArray();

		if (src[index] == target[index]) {
			if (src.length == index + 1) {
				// 完全まっち! => END
				this.cost = Math.min(cost, this.cost);
			} else {
				solve(s, t, index + 1, cost);
			}
		} else {
			int pos = index;
			LinkedList<Integer> hit = new LinkedList<Integer>();
			while (true) {
				pos = search(target, src[index], pos);
				if (pos == -1) break;
				hit.add(pos++);
			}

			if (hit.size() > 0) {
				while (hit.size() > 0) {
					int to = hit.poll();
					swap(target, index, to);
					solve(s, new String(target), index + 1, cost + 1);
					swap(target, to, index);
				}
			}
		}
	}

	public void swap(char[] c, int from, int to) {
		char temp = c[from];
		c[from] = c[to];
		c[to] = temp;
	}

	public int search(char[] c, char target, int start) {
		for (int i = start; i < c.length; i++) {
			if (c[i] == target)
				return i;
		}
		return -1;
	}
}

0.0

でも、競技中に間に合わなかった(笑
超レート下がったyo