usaco 4.4.3 Frame Up

来源:互联网 发布:什么电子书软件好用 编辑:程序博客网 时间:2024/05/26 15:57

 

/*ID: daniel.20LANG: JAVATASK: frameup*/import java.util.*;import java.io.*;import java.math.BigInteger;class problem22{    StringBuilder sb = new StringBuilder();    long start = System.currentTimeMillis();    int H,W;    char[][] arr;    int left[] = new int[26];    int right[] = new int[26];    int top[] = new int[26];    int bottom[] = new int[26];    boolean vis[] = new boolean[26];    ArrayList<String> l = new ArrayList<String>();    int[][] relation = new int[26][26];    int count[] = new int[26];    char[] path = new char[26];    int total = 0;    void solver() throws IOException{           BufferedReader reader = new BufferedReader(new FileReader("frameup.in"));        Arrays.fill(left, 999);        Arrays.fill(right, -1);        Arrays.fill(top, 999);        Arrays.fill(bottom, -1);        StringTokenizer st = new StringTokenizer(reader.readLine());        H=Integer.valueOf(st.nextToken());        W=Integer.valueOf(st.nextToken());        arr = new char[H][W];        for(int i=0;i<H;i++){            String tmp = reader.readLine();            for(int j=0;j<W;j++){                arr[i][j]=tmp.charAt(j);                if(arr[i][j]=='.') continue;                int temp = arr[i][j]-'A';                left[temp]=left[temp]<j?left[temp]:j;                right[temp]=right[temp]>j?right[temp]:j;                top[temp]=top[temp]<i?top[temp]:i;                bottom[temp]=bottom[temp]>i?bottom[temp]:i;            }        }        for(int i=0;i<26;i++){            if(left[i]==999) continue;            int cnt=0;            total++;            for(int k1=left[i];k1<=right[i];k1++){                if(arr[top[i]][k1]-'A'!=i){                    relation[i][arr[top[i]][k1]-'A'] = -1;                    cnt++;                }                if(arr[bottom[i]][k1]-'A'!=i){                    relation[i][arr[bottom[i]][k1]-'A'] = -1;                    cnt++;                }                            }            for(int k2=top[i];k2<=bottom[i];k2++){                if(arr[k2][left[i]]-'A'!=i){                    relation[i][arr[k2][left[i]]-'A'] = -1;                    cnt++;                }                if(arr[k2][right[i]]-'A'!=i){                    relation[i][arr[k2][right[i]]-'A'] = -1;                    cnt++;                }                           }            count[i]= cnt;        }        for(int i=0;i<26;i++){            if(left[i]==999||!ok(i)) continue;            path[0]=(char)(i+'A');            dfs(i,1);              path[0]=0;        }        Collections.sort(l);        for(String x:l){            sb.append(x).append("\n");        }        //System.out.print(sb.toString());        PrintWriter pw = new PrintWriter(new BufferedWriter(new FileWriter("frameup.out")));        pw.print(sb.toString());        pw.close();        System.out.println("$:"+(System.currentTimeMillis()-start));        System.exit(0);             }    boolean ok(int n){        for(int i=0;i<26;i++){            if(left[i]==999) continue;            if(!vis[i]&&relation[i][n]==-1) return false; //i should be before n, so when we about to place n, vis[i] should be true        }        return true;    }    void dfs(int c, int level){        if(level==total){            String s = new String(path,0,level);            l.add(s);            return;        }        vis[c]=true;        for(int i=0;i<26;i++){            if(left[i]==999||vis[i]) continue;            if(ok(i)){                path[level]=(char)(i+'A');                dfs(i,level+1);                     path[level]=0;                }        }        vis[c]=false;          }}public class frameup {    public static void main(String[] args) throws Exception {        problem22 p = new problem22();        p.solver();    }}

拓扑排序倒过来搞,这个是正确的方法。
0 0
原创粉丝点击