3.约束排列(place.pas/cpp/in/out)
问题描述:
给出 n 个互不相同的小写字母,表示出现的字符类型,以及 k 个约束关系: .....,表示 ai 必须出现在 bi 前面(ai,bi 不会超出所给字符类型的范围,且
ai!=bi)。
请按照字典序输出所有满足约束条件的序列。
如:
n=3,字符类型为:x y z
k=1,约束条件为:x z,表示 x 必须出现在 z 的前面。
所有满足约束条件的排列有:
xyz
xzy
yxz
输入:
第 1 行,2 个整数 n 和 k。
第 2 行,n 个空格隔开的字符。
接下来 k 行,每行二个字符 ai 和 bi(表示约束关系),数据保证不会出现矛盾的关系。
输出:
若干行,每行 n 个字符(字符之间没有空格),表示排列的结果。
样例输入:
3 1
x y z
x z
样例输出:
xyz
xzy
yxz
数据范围:
对于 100%的数据:1<n<9,1≤k≤8。
思路
数据真的小,直接全排列,枚举即可。
对于检查是否满足K个约束,直接枚举,对于每个约束,如果先出现"应该先出现的"那就满足要求,如果先出现“应该后出现的”,那就不满足,标记之后再退出。
满足所有约束的就输出。
next_permutation( a + 1, a + n + 1 ):转为下一个全排列,没有了就返回0
(真搞不懂这种题目为嘛放T3???逗我么??估计普及-。。。)
代码
#include<bits/stdc++.h>
using namespace std;
int N, K;
char s[20];
char a[20], b[20];
inline char Get(){
char ans; while( ( ans = getchar() ) < 'a' || ans > 'z' );
return ans;
}
int main(){
freopen( "place.in", "r", stdin );
freopen( "place.out", "w", stdout );
scanf( "%d%d", &N, &K );
for ( int i = 1; i <= N; ++i ) s[i] = Get();
for ( int i = 1; i <= K; ++i ) a[i] = Get(), b[i] = Get();
sort( s + 1, s + N + 1 ); s[N + 1] = ' ';
do{
bool flg(1);
for ( int i = 1; i <= K; ++i )
for ( int j = 1; j <= N; ++j ){
if ( s[j] == a[i] ) break;
if ( s[j] == b[i] ){ flg = 0; break; }
}
if ( flg ) printf( "%s
", s + 1 );
}while( next_permutation( s + 1, s + N + 1 ) );
return 0;
}