TopCoder SRM 398 Level2 900
http://www.topcoder.com/stat?c=problem_statement&pm=8160
一组字符串,如何将其中一部分右移若干格,使得某一列的纵向恰好为要求的字符串,并且给出移动最少的答案。

这一题乍一看觉得很复杂
有点像之前做过的吉他琴弦的那一题
可是这个复杂度2^50是吃不消的
但是这里有两点不同
一个是这里只能右移
另一个很重要的是这个某一列将成为一个有参考意义的坐标
即用这个列号来遍历 看答案在哪一列解答最少
想通这一点 后面就很容易了
 1import java.util.*;
 2import java.util.regex.*;
 3import java.text.*;
 4import java.math.*;
 5import java.awt.geom.*;
 6
 7public class MatchString
 8{
 9    public int placeWords(String matchString, String[] matchWords)
10    {
11        List<ArrayList<Integer> > occur = new ArrayList<ArrayList<Integer> >();
12        int L = matchWords.length;
13        int end = 0;
14        int start = Integer.MAX_VALUE;
15        int i,j;
16        for(i = 0 ; i < L ; ++ i){
17            ArrayList<Integer> temp = new ArrayList<Integer>();
18            char c = matchString.charAt(i);
19            for(j = 0 ; j < matchWords[i].length(); ++ j){
20                if(matchWords[i].charAt(j) == c)
21                    temp.add(j);
22            }

23            if(temp.isEmpty()) return -1;
24            occur.add(temp);
25            if(matchWords[i].length() > end)
26                end = matchWords[i].length();
27            if(temp.get(0< start)
28                start = temp.get(0);
29        }

30        int ans = Integer.MAX_VALUE;
31        Outer:
32        for(i = start; i <= end; ++ i){
33            int tempans = 0;
34            for(int k = 0 ; k < L; ++ k){
35                j = 0;
36                while(j < occur.get(k).size() && occur.get(k).get(j) <= i)
37                    ++j;
38                if(j == 0)
39                    continue Outer;
40                tempans += i - occur.get(k).get(j-1);                
41            }

42            ans = Math.min(ans, tempans);
43        }

44        return ans;
45    }

46}