方法:dfs
思想:利用搜索或next_permutation产生下一个排列,然后判断该排列是否满足
要求,如果满足要求输出即可。
代码:
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
char var[50],t[50];
char constraint[105][2];
bool visited[50];
int n,m,pos[305];
void dfs(int k)
{
int i,j;
if(k==n)
{
//更新字符所对应的位置
for(i=0;i<m;i++)
{ for(j=0;j<n;j++)
if(constraint[i][0]==t[j])
{ pos[constraint[i][0]]=j; break;}
for(j=0;j<n;j++)
if(constraint[i][1]==t[j])
{ pos[constraint[i][1]]=j; break;}
}
// 看是否存在违背限制的字符对
for(i=0;i<m;i++)
{ for(j=pos[constraint[i][0]]-1;j>=0;j--)
if(t[j]==constraint[i][1])break;
if(j>=0)break;
}
if(i<m)return;//有违背限制的,不需要输出
for(i=0;i<n;i++)
if(i<n-1)cout<<t[i];
else cout<<t[i]<<endl;
return;
}
for(i=0;i<n;i++)
if(visited[i]==0)
{
char tmp=var[k];pos[k]=i;
t[k]=var[i];visited[i]=1;
dfs(k+1);
t[k]=tmp;visited[i]=0;pos[k]=k;
}
}
int main()
{
int flag=0;
char c;
n=0,m=0;
while(scanf("%c",&c)!=EOF)
{
if(c>='a'&&c<='z')var[n++]=c;
while((c=getchar())!='\n')
if(c!=' '){ var[n]=c;pos[c]=n;n++;}
while((c=getchar())!='\n')
if(c!=' ')
{
if(m%2==0)constraint[m/2][0]=c;
else constraint[m/2][1]=c;
m++;
}
m/=2;
int i,j;
if(flag)cout<<endl;
sort(var,var+n);//必须排序,否则wrong answer
dfs(0);
n=0;m=0;flag=1;
}
return 0;
}
代码二:使用next_permutation
#include <iostream>
#include <algorithm>
using namespace std;
int n,m;//n个变量,m个限制
char var[50];
char constraint[105][2];
int pos[150];
int main(int argc, char *argv[])
{
int flag=0;
char c;
n=0;m=0;
while(scanf("%c",&c)!=EOF)
{
if(c>='a'&&c<='z')var[n++]=c;
while((c=getchar())!='\n')
if(c!=' '){ var[n]=c;pos[c]=n;n++;}
while((c=getchar())!='\n')
if(c!=' ')
{
if(m%2==0)constraint[m/2][0]=c;
else constraint[m/2][1]=c;
m++;
}
m/=2;
int i,j;
if(flag)cout<<endl;
sort(var,var+n);
//注意在排列变化的过程中字符对应的位置也要相应更新
/*for(i=0;i<m;i++)
cout<<constraint[i][0]<<' '<<constraint[i][1]<<endl
<<pos[constraint[i][0]]<<' '<<pos[constraint[i][1]]<<endl;
*/
do
{
//修改排列变化后字符所对应的位置
for(i=0;i<m;i++)
{ for(j=0;j<n;j++)
if(constraint[i][0]==var[j])
{ pos[constraint[i][0]]=j; break;}
for(j=0;j<n;j++)
if(constraint[i][1]==var[j])
{ pos[constraint[i][1]]=j; break;}
}
// 看是否存在违背限制的字符对
for(i=0;i<m;i++)
{ for(j=pos[constraint[i][0]]-1;j>=0;j--)
if(var[j]==constraint[i][1])break;
if(j>=0)break;
}
if(i<m)continue;
for(i=0;i<n;i++)
if(i<n-1)cout<<var[i];
else cout<<var[i]<<endl;
}
while(next_permutation(var,var+n));
n=0;m=0;flag=1;
}
return 0;
}
这两个代码都只能在buct上AC,在pku上均RE,不知道什么原因,还有待进一步考虑。