【2018-12-02模拟赛】T3 约束排列 解题报告

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] = '\0';
    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\n", s + 1 );
    }while( next_permutation( s + 1, s + N + 1 ) );
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/louhancheng/p/10055071.html