zoukankan      html  css  js  c++  java
  • 2019 年百度之星·程序设计大赛

    传送门:

      [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=egin{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} egin{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 ? '
    ':' ');
    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)

    •感想

      比赛的时候搜索,TLE,并未想到如果 S 中的第 j 列在 T 中找到一个满足的时候就找到当前 j 的对应列;

      并且以后在查找的时候,之前找到的列并不影响答案的正确性,由此衍生出了 O(n·m2) 的解法;

      而上述解法是在参阅了 rank1 的代码后提取出的思路,tql;

     1 #include<bits/stdc++.h> 
     2 #define For(i,j,k) for (int i=(int)(j);i<=(int)(k);i++)
     3 #define Rep(i,j,k) for (int i=(int)(j);i>=(int)(k);i--)
     4 #define pii pair<int,int>
     5 #define pll pair<ll,ll>
     6 #define ll long long
     7 #define fi first
     8 #define se second
     9 #define PB push_back
    10 #define uint unsigned
    11 #define ull unsigned ll 
    12 using namespace std;
    13 pll hsh1[55],hsh2[55];
    14 int n,m,ans[55];
    15 char s[55];
    16 void solve(){
    17     scanf("%d%d",&n,&m);
    18     For(i,1,m) hsh1[i]=hsh2[i]=pll(0,i);
    19     For(i,1,n){
    20         scanf("%s",s+1);
    21         For(j,1,m) hsh1[j].fi=hsh1[j].fi*233+s[j];
    22         scanf("%s",s+1);
    23         For(j,1,m) hsh2[j].fi=hsh2[j].fi*233+s[j];
    24     }
    25     sort(hsh1+1,hsh1+m+1);
    26     sort(hsh2+1,hsh2+m+1);
    27     For(i,1,m)
    28         if (hsh1[i].fi!=hsh2[i].fi)
    29             return puts("-1"),void(0);
    30     For(i,1,m)
    31         ans[hsh1[i].se]=hsh2[i].se;
    32     For(i,1,m) printf("%d%c",ans[i],i==m?'
    ':' ');
    33 }
    34 int main(){
    35     int T;
    36     scanf("%d",&T);
    37     while (T--) solve(); 
    38 }
    O(n·m),字符串哈希
  • 相关阅读:
    HTTP协议
    浏览器兼容性问题
    面试笔试重点总结:操作系统、计算机网络、设计模式
    笔试、面试重点总结:算法基础、数据结构
    笔试、面试重点总结:WIN32、MFC与Linux
    《Java程序员面试笔试宝典》终于在万众期待中出版啦~
    《Java程序员面试笔试宝典》之Static关键字有哪些作用
    《Java程序员面试笔试宝典》之字符串创建与存储的机制是什么
    《Java程序员面试笔试宝典》之为什么需要public static void main(String[] args)这个方法
    《Java程序员面试笔试宝典》之Java变量命名有哪些规则
  • 原文地址:https://www.cnblogs.com/violet-acmer/p/11377995.html
Copyright © 2011-2022 走看看