题目大意:给你很多个单词,以‘#’结尾,单词以字典序输入,然后是第二部分,给你几个短语,问你用上面的单词去组合,这几个单词中的字幕可以随意搞换顺序,而且必须要有字母的顺序变动,然后让你把这些所有的组合都输出来。
思路:爆搜。因为顺序可以随便,也就是只要字母个数对就可以了,读进去的时候就预处理出每个字符串中每个字母的出现个数,可以开一个长度为26的数组存,递归的时候,把个数减掉,发现如果个数不是完全包含的,不往下,递归的时候顺带记录路径,回溯的时候在把减掉的个数加回来就好了,如果所有的字母个数都为0,那么就是答案了。还有一个要特判单词和短语完全相同的情况,这个只需要把短语中的单词拿出来,排序,再拼起来,用这个去判断跟那几个单词拼起来的一不一样就好了。
处理字符串,思路是挺简单的,不过写起来真心有点烦,输入还不能直接拉,因为 ‘#’ 后面有个空格。。 = =
代码如下:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
char dir[2222][22];
int dir_num[2222][33],tot;
int num[33];
int path[2222];
char pha[44];
struct Word
{
char str[22];
} word[22];
int cmp(Word a,Word b)
{
return strcmp(a.str,b.str) < 0 ? 1 : 0 ;
}
char check[22],tmp[22];
void dfs(int pos,int path_pos)
{
int c = 0;
for(int i = 0;i<26;i++)
c += num[i];
if(c == 0)
{
int cc = 0;
for(int i = 0;i<path_pos;i++)
for(int j = 0;j<dir[path[i]][j];j++)
tmp[cc ++] = dir[path[i]][j];
tmp[cc] = '\0';
//puts(tmp);
if(strcmp(tmp,check) == 0) return ;
printf("%s = ",pha);
for(int i = 0;i<path_pos;i++)
{
if(i == 0) printf("%s",dir[path[i]]);
else printf(" %s",dir[path[i]]);
}
puts("");
}
for(int i = pos + 1;i<tot;i++)
{
int ok = 1;
for(int j = 0;j<26;j++)
{
num[j] -= dir_num[i][j];
if(num[j] < 0)
{
ok = 0;
}
}
if(ok)
{
path[path_pos ++] = i;
dfs(i,path_pos);
path_pos --;
}
for(int j = 0;j<26;j++)
num[j] += dir_num[i][j];
}
}
int main()
{
while(~scanf("%s",dir[0]))
{
tot = 1;
memset(dir_num[0],0,sizeof(dir_num[0]));
for(int i = 0;dir[0][i];i++)
dir_num[0][dir[0][i] - 'A']++;
while(1)
{
scanf("%s",dir[tot]);
if(dir[tot][0] == '#') break;
memset(dir_num[tot],0,sizeof(dir_num[tot]));
for(int i = 0;dir[tot][i];i++)
dir_num[tot][dir[tot][i] - 'A']++;
tot ++;
}
getchar();
//printf("tot = %d\n",tot);
while(1)
{
gets(pha);
if(pha[0] == '#') break;
//puts(pha);
int cc = 0;
int pos = 0;
for(int i = 0;pha[i];i++)
{
if(pha[i] == ' ')
{
word[cc].str[pos] = '\0';
cc++;
pos = 0;
}
else word[cc].str[pos ++] = pha[i];
}
word[cc].str[pos] = '\0';
cc ++;
sort(word,word+cc,cmp);
//for(int i = 0;i<cc;i++)
//puts(word[i].str);
pos = 0;
for(int i = 0;i<cc;i++)
{
for(int j = 0;word[i].str[j];j++)
check[pos++] = word[i].str[j];
}
check[pos] = '\0';
//puts(check);
memset(num,0,sizeof(num));
for(int i = 0;pha[i];i++)
{
if(pha[i] == ' ') continue;
num[pha[i] - 'A'] ++;
}
dfs(-1,0);
}
}
return 0;
}
/*
ABC
AND
DEF
DXZ
K
KX
LJSRT
LT
PT
PTYYWQ
Y
YWJSRQ
ZD
ZZXY
#
ZZXY ABC DEF
SXZYTWQP KLJ YRTD
ZZXY YWJSRQ PTYYWQ ZZXY
#
*/