想看更多的解题报告:http://blog.csdn.net/wangjian8006/article/details/7870410
转载请注明出处:http://blog.csdn.net/wangjian8006
题目大意:给出两行字符串,第一行代表有哪些点,第二行有很多个字符,每两个字符A,B代表A<B
问满足条件的所有答案
比如有a b f g四个点
然后a b b f,代表a<b并且b<f
现在要求输出的一个由所有点组成的字符串,并且不能出现b>a和b>f的情况
解题思路:咋一看和拓扑排序没什么区别,但是要求输出所有的结果,那么用拓扑排序输出就有点麻烦了
所以直接写了一个全排列,加一些条件就可以了,所以只要输出满足这个条件的所有排列即可
/*
Memory 172K
Time 16MS
*/
#include <iostream>
#include <string.h>
using namespace std;
#define MAXV 30
#define MAXS 500
char s[MAXS];
int mark[MAXV],n,num,ans[MAXV],vis[MAXV],map[MAXV][MAXV];
int find(int i,int cap){ //如果前面已经找到的比i还小了就返回0
int j;
for(j=0;j<cap;j++)
if(map[i][ans[j]]) return 0;
return 1;
}
void dfs(int cap){
int i;
if(cap==num){
for(i=0;i<cap;i++) printf("%c",ans[i]+'a');
printf("\n");
}
for(i=0;i<26;i++){
if(mark[i] && !vis[i] && find(i,cap)){ //vis表示是否已经找到了
ans[cap]=i;
vis[i]=1;
dfs(cap+1);
vis[i]=0;
}
}
}
int main(){
int len,i,j;
n=26;
while(gets(s)){
memset(mark,0,sizeof(mark)); //这个标记哪些个点存在
len=strlen(s);
num=0;
for(i=0;i<len;i++){
if(s[i]!=' '){
mark[s[i]-'a']=1;
}
}
memset(map,0,sizeof(map));
gets(s);
len=strlen(s);
for(i=0;i<len;i++){
if(s[i]!=' '){
for(j=i+1;j<len;j++)
if(s[j]!=' '){
map[s[i]-'a'][s[j]-'a']=1; //建立一个大小的关系,如果map[i][j]==1就表示i大于j
break;
}
i=j;
}
}
memset(vis,0,sizeof(vis));
dfs(0);
printf("\n");
}
return 0;
}