传送门:

  [1]:HDU

  [2]:bestcoder

 

 

B.度度熊与排列(思维)

•题意

  有一个数组 p,p 中包含的数为 1~m 的全排列,一个含 m 个字符的串 s;

  在 s 上有一个操作,对于 s 中的第 i 个位置的字符,放到 p[ i ] 位置,构成一个新串 t;

  即 $s_{i}=t_{p_i}$;

  给你 2n 个串,每两个串为一组,前一个串表示原串 s,后一个串表示经过 p 映射后的新串 t;

  求是否存在某个 1~m 的全排列,使得这 n 组串都可以经过 p 由 s 变为 t;

  如果存在,输出字典序最小的那组,如果不存在,输出 -1;

•题解

  $S=\begin{bmatrix} s_1: & s_{11} & s_{12} & \cdots & s_{1m} \\ s_2: & s_{21} & s_{22} & \cdots & s_{2m} \\ s_3: & s_{31} & s_{32} & \cdots & s_{3m} \\ \vdots & \vdots & \vdots & \vdots \ \vdots & \vdots \\s_n: & s_{n1} & s_{n2} & \cdots & s_{nm} \end{bmatrix} \ \ \underrightarrow {p} \ \ \begin{bmatrix} t_1: & t_{11} & t_{12} & \cdots & t_{1m} \\ t_2: & t_{21} & t_{22} & \cdots & t_{2m} \\ t_3: & t_{31} & t_{32} & \cdots & t_{3m} \\ \vdots & \vdots & \vdots & \vdots \ \vdots & \vdots \\t_n: & t_{n1} & t_{n2} & \cdots & t_{nm} \end{bmatrix}=T$

  $s_{i,j}\ \underrightarrow {p} \ t_{i,p_j}$;

  对于 S 中的第 j 列,经过映射变成 T 中的第 pj 列;

  可以将 S,T 中的各个列以字符串的形式存下来;

  对于 Sj ,判断 T 中是否存在未被标记 Sj,如果存在,找出字典序最小的那个对应过去即可,并标记;

  如果不存在,输出 -1;

•Code

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define fi first
 4 #define se second
 5 const int maxn=60;
 6 
 7 int n,m;
 8 char s[maxn];
 9 int ans[maxn];
10 pair<string ,int >f[maxn],g[maxn];
11 
12 void Solve()
13 {
14     ///f,g分别拍完序后,第i个的first要对应才有解
15     for(int i=1;i <= m;++i)
16         if(f[i].fi != g[i].fi)
17             return puts("-1"),void(0);
18 
19     for(int i=1;i <= m;++i)
20         ans[f[i].se]=g[i].se;
21 
22     for(int i=1;i <= m;++i)
23         printf("%d%c",ans[i],i == m ? '\n':' ');
24 }
25 int main()
26 {
27     int T;
28     scanf("%d",&T);
29     while(T--)
30     {
31         scanf("%d%d",&n,&m);
32 
33         for(int i=1;i <= m;++i)
34             f[i]=g[i]=make_pair("",i);
35 
36         for(int i=1;i <= n;++i)
37         {
38             scanf("%s",s+1);
39             for(int j=1;j <= m;++j)
40                 f[j].fi += s[j];
41 
42             scanf("%s",s+1);
43             for(int j=1;j <= m;++j)
44                 g[j].fi += s[j];
45         }
46 
47         sort(f+1,f+m+1);
48         sort(g+1,g+m+1);
49 
50         Solve();
51     }
52     return 0;
53 }
O(n·m)

相关文章: