SRM454 div2
眠いけど、一応出た。
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
