传送门:
[1]:HDU
[2]:bestcoder
B.度度熊与排列(思维)
•题意
有一个数组 p,p 中包含的数为 1~m 的全排列,一个含 m 个字符的串 s;
在 s 上有一个操作,对于 s 中的第 i 个位置的字符,放到 p[ i ] 位置,构成一个新串 t;
即 si=tpisi=tpi;
给你 2n 个串,每两个串为一组,前一个串表示原串 s,后一个串表示经过 p 映射后的新串 t;
求是否存在某个 1~m 的全排列,使得这 n 组串都可以经过 p 由 s 变为 t;
如果存在,输出字典序最小的那组,如果不存在,输出 -1;
•思路
就s->t可以对应实现而言
每个s串的每个位置的字母,与每个t串的对应位置的字母是相同的
例如
s串 t串
abcdda addcba
azxcvv vvcxza
s串每个位置字母
1 2 3 4 5 6
a b c d d a
a z x c v v
t串每个位置字母
1 2 3 4 5 6
a d d c b a
v v c x z a
所以s与t位置对应
1->6,2->5,3->4,4->3,5->2,6->1
为了方便查找,我们可以将s串每一列按字典序排序,t串每一列按字典序排序
于是变成
s串
1 6 2 3 4 5
a a b c d d
a v z x c v
t串
6 1 5 4 3 2
a a b c d d
a v z x c v
排序之后s的每一列,与t的每一列应该是完全相同的,
s与t所对应的序号,就是对应的位置
•代码
View Code1 #include<bits/stdc++.h> 2 using namespace std; 3 4 pair<string,int> p1[55],p2[55]; 5 string s[25],t[25]; 6 7 int main() 8 { 9 int T; 10 cin>>T; 11 while(T--) 12 { 13 int n,m; 14 cin>>n>>m; 15 for(int i=1;i<=n;i++) 16 cin>>s[i]>>t[i]; 17 18 for(int j=0;j<m;j++) 19 { 20 string x,y; 21 for(int i=1;i<=n;i++) 22 { 23 x+=s[i][j]; 24 y+=t[i][j]; 25 } 26 p1[j].first=x,p2[j].first=y; 27 p1[j].second=j+1,p2[j].second=j+1; 28 } 29 sort(p1,p1+m); 30 sort(p2,p2+m); 31 32 int index[55]; 33 bool flag=true; 34 for(int i=0;i<m;i++) 35 { 36 if(p1[i].first!=p2[i].first) 37 { 38 puts("-1"); 39 flag=false; 40 break; 41 } 42 index[p1[i].second]=p2[i].second; 43 } 44 if(!flag) 45 continue; 46 for(int i=1;i<=m;i++) 47 { 48 if(i!=1) 49 printf(" %d",index[i]); 50 else 51 printf("%d",index[i]); 52 } 53 puts(""); 54 } 55 }