poj1171 是这个题的简化版,我的思路是全排列字母,用tire树把字典里的东西都存起来,写的非常麻烦。。。全排列简单dfs就可以,得到结果 判断此字符串是不是在字典里,分割是不是在字典里。。。写的很繁琐,一直MLE,我看不懂题意,还一直以为是读入问题呢,把最后结果map水了一下。。。终于过了,太恶心了。
1 /* 2 ID:cuizhe 3 LANG: C++ 4 TASK: lgame 5 */ 6 #include <cstdio> 7 #include <cmath> 8 #include <cstring> 9 #include <cstdlib> 10 #include <iostream> 11 #include <string> 12 #include <map> 13 #include <queue> 14 #include <algorithm> 15 using namespace std; 16 map<string,int> mp; 17 int n,t = 0; 18 int aim[26] = {2,5,4,4,1,6,5,5,1,7,6,3,5,2,3,5,7,2,1,2,4,6,6,7,5,7}; 19 char str[8]; 20 int o[8]; 21 int maxz = 0,inf; 22 int tire[100000][27]; 23 int flag[100000]; 24 int top; 25 char pos[100][10]; 26 void build(char *p) 27 { 28 int i,root = 0,len; 29 len = strlen(p); 30 for(i = 0; i < len; i ++) 31 { 32 if(tire[root][p[i]-'a']) 33 ; 34 else 35 tire[root][p[i]-'a'] = t ++; 36 root = tire[root][p[i]-'a']; 37 } 38 flag[root] = 1; 39 } 40 int find(char *p) 41 { 42 int i,root = 0,len; 43 len = strlen(p); 44 for(i = 0; i < len; i ++) 45 { 46 if(tire[root][p[i]-'a']) 47 root = tire[root][p[i]-'a']; 48 else 49 break; 50 } 51 if(i == len&&flag[root]) return 1; 52 else return 0; 53 } 54 void dfs(int x) 55 { 56 int i,j,sum = 0,len; 57 char ch[8],l[6],r[6]; 58 int w[201]; 59 memset(w,0,sizeof(w)); 60 if(x > n) 61 { 62 sum = inf; 63 len = n; 64 for(i = 1; i <= len; i ++) 65 { 66 for(j = 0; j < len; j ++) 67 { 68 if(o[j] == i) 69 { 70 ch[i-1] = str[j]; 71 break; 72 } 73 } 74 } 75 ch[len] = '\0'; 76 for( ; len >= 3; sum -= aim[ch[len-1]-'a'],len--) 77 { 78 ch[len] = '\0'; 79 if(find(ch) == 1&&sum >= maxz) 80 { 81 if(sum > maxz) 82 { 83 maxz = sum; 84 top = 0; 85 strcpy(pos[top],ch); 86 top ++; 87 } 88 else if(maxz == sum) 89 { 90 strcpy(pos[top],ch); 91 top ++; 92 } 93 } 94 if(len < 6) continue; 95 for(i = 0; i < 3; i ++) 96 l[i] = ch[i]; 97 l[i] = '\0'; 98 for(; i < len; i ++) 99 r[i-3] = ch[i]; 100 r[i-3] = '\0'; 101 if(strcmp(l,r) < 0) 102 { 103 if(find(l)&&find(r)&&sum >= maxz) 104 { 105 if(sum > maxz) 106 top = 0; 107 maxz = sum; 108 for(i = 0; i < 3; i ++) 109 pos[top][i] = l[i]; 110 pos[top][3] = ' '; 111 for(i = i+1,j = 0; r[j]; i ++,j ++) 112 pos[top][i] = r[j]; 113 pos[top][i] = '\0'; 114 top ++; 115 } 116 } 117 for(i = 0; i < 4; i ++) 118 l[i] = ch[i]; 119 l[i] = '\0'; 120 for(; i < len; i ++) 121 r[i-4] = ch[i]; 122 r[i-4] = '\0'; 123 if(strcmp(l,r) < 0) 124 { 125 if(find(l)&&find(r)&&sum >= maxz) 126 { 127 if(sum > maxz) 128 top = 0; 129 maxz = sum; 130 for(i = 0; i < 4; i ++) 131 pos[top][i] = l[i]; 132 pos[top][4] = ' '; 133 for(i = i+1,j = 0; r[j]; i ++,j ++) 134 pos[top][i] = r[j]; 135 pos[top][i] = '\0'; 136 top ++; 137 } 138 } 139 } 140 } 141 for(i = 0; i < n; i ++) 142 { 143 if(!o[i]&&!w[str[i]]) 144 { 145 w[str[i]] = 1; 146 o[i] = x; 147 dfs(x+1); 148 o[i] = 0; 149 } 150 } 151 } 152 int main() 153 { 154 int i,j; 155 char temp; 156 char ch[10]; 157 freopen("lgame.dict","r",stdin); 158 while(scanf("%s",ch)!=EOF) 159 { 160 if(strcmp(ch,".") == 0) break; 161 build(ch); 162 } 163 freopen("lgame.in","r",stdin); 164 freopen("lgame.out","w",stdout); 165 scanf("%s",str); 166 n = strlen(str); 167 inf = 0; 168 for(i = 1; i <= n-1; i ++) 169 { 170 for(j = 0; j <= n-i-1; j ++) 171 { 172 if(str[j] > str[j+1]) 173 { 174 temp = str[j]; 175 str[j] = str[j+1]; 176 str[j+1] = temp; 177 } 178 } 179 } 180 for(i = 0; i < n; i ++) 181 inf += aim[str[i]-'a']; 182 dfs(1); 183 printf("%d\n",maxz); 184 for(i = 0; i < top; i ++) 185 { 186 if(!mp[pos[i]]) 187 { 188 mp[pos[i]] = 1; 189 printf("%s\n",pos[i]); 190 } 191 } 192 return 0; 193 }