POJ 3504 HASH

来源:互联网 发布:苹果变音软件 编辑:程序博客网 时间:2024/06/05 19:14

题意

一堆字符串由许多个单词组成,但是除了单词的开始和结尾都做了一定程度的乱序。要求破解这个被打乱的句子。

题解

HASH+DP(暴力)。首先对单词进行处理,将单词去掉头和尾记录到头和尾组成的哈希表中。对于长度为1的单词特殊记录。然后进行暴力搜索(DP)。暴力搜索从0开始,0可能是从0开始到0-100区间内组成的任意一个的单词的字符(因为单词长度最大为100,这个需要特别注意,会不会TLE就看这个了)。于是我们便可以去针对每一个可能的字符串去哈希表里搜索,如果搜索到了那么就可以进行状态转移。
对于一个单词,可以状态转移到现有长度+单词长度的位置。因为涉及到是否存在模糊字符串的判断,因此在转移的时候需要分情况讨论。对于模糊的单词,状态转移之后的值应该为2。而对于非模糊的单词,则应该视情况而定,并且需要记录对应单词,因为非模糊单词是有可能组成最后结果的。
最后暴力搜索完以后,判断一下是否能形成合法答案,输出一下就可以了。

代码

import java.util.ArrayList;import java.util.Arrays;import java.util.Collections;import java.util.HashMap;import java.util.HashSet;import java.util.List;import java.util.Map;import java.util.Scanner;import java.util.Set;public class Main{    public static void main(String[] args) {        Scanner scanner=new Scanner(System.in);        int ks=scanner.nextInt();        Map<String, String> first[][]=new HashMap[30][30];        Set<String> second[][]=new HashSet[30][30];        for (int i = 0; i < 30; i++) {            for (int j = 0; j < 30; j++) {                first[i][j]=new HashMap<String,String>();                second[i][j]=new HashSet<String>();            }        }        while(ks!=0){            boolean single[]=new boolean[30];            String string=scanner.next();            int len=string.length();            ks--;            int n=scanner.nextInt();            for (int i = 0; i < 30; i++) {                for (int j = 0; j < 30; j++) {                    first[i][j].clear();                    second[i][j].clear();                }            }            for (int i = 0; i < n; i++) {                String word=scanner.next();                if(word.length()==1){                    single[word.charAt(0)-'a']=true;                }else{                    int a=word.charAt(0)-'a';                    int b=word.charAt(word.length()-1)-'a';                    char arr[]=word.substring(1, word.length()-1).toCharArray();                    Arrays.sort(arr);                    String sortStr=String.valueOf(arr);                    if(first[a][b].containsKey(sortStr)){                        second[a][b].add(sortStr);                    }else {                        first[a][b].put(sortStr, word);                    }                }            }            int way[]=new int[1100];            String pre[]=new String[1100];            way[0]=1;            for (int i = 0; i < len; i++) {                if(way[i]>0){                    if(single[string.charAt(i)-'a']){                        way[i+1]=Math.min(way[i+1]+way[i],2);                        pre[i+1]=String.valueOf(string.charAt(i));                    }                    for (int j = i+2; j <= len&&(j-i)<=100; j++) {                        int a=string.charAt(i)-'a';                        int b=string.charAt(j-1)-'a';                        String word=string.substring(i+1, j-1);                        char arr[]=word.toCharArray();                        Arrays.sort(arr);                        String sortStr=String.valueOf(arr);                        if(second[a][b].contains(sortStr)){                            way[j]=Math.min(way[j]+2*way[i],2);                        }else if(first[a][b].containsKey(sortStr)){                            way[j]=Math.min(way[j]+way[i],2);                            pre[j]=first[a][b].get(sortStr);                        }                    }                }            }            if(way[len]==2){                System.out.println("ambiguous");            }else if(way[len]==0){                System.out.println("impossible");            }else {                List<String> ans=new ArrayList<String>();                for(int i=len;i>0;i-=pre[i].length()){                    ans.add(pre[i]);                }                Collections.reverse(ans);                for (int i = 0; i < ans.size(); i++) {                    if(i!=0)                        System.out.print(" ");                    System.out.print(ans.get(i));                }                System.out.println();            }        }    }}
原创粉丝点击