zoukankan      html  css  js  c++  java
  • 度度熊与排列[搜索+剪枝]----2019 年百度之星·程序设计大赛

    度度熊与排列

     
     Accepts: 1100
     
     Submissions: 3486
     Time Limit: 2000/1000 MS (Java/Others)
     
     Memory Limit: 32768/32768 K (Java/Others)
    Problem Description

    度熊有一个机器,这个机器有一个 1 sim M1M 的排列 p[1..M]p[1..M] 当作参数,若丢进一个长度为 MM 的字符串,此机器会将此字符串重新排列后再输出,重新排列的方式为:原本第 ii 个位置的字符会变到第 p[i]p[i] 个位置。

    举例来说,当 M = 3M=3p[1]=3,p[2]=1,p[3]=2p[1]=3,p[2]=1,p[3]=2,那么丢 "abc" 进入这个机器后,机器会输出"bca";若丢进的是 "ded",那么机器会输出 "edd"。

    某天,度熊不小心忘记这个机器的参数了,只记得参数的长度是 MM,于是他丢了 NN 长度为 MM 的字符串进去,并记录下对于每个字符串机器的输出结果,请你根据这些结果,帮度熊找回这个机器的参数。若有多组参数都满足度熊的记录,请输出字典序最小的排列作为参数。若并不存在任何参数满足度熊的记录,请输出 -11

    注:对于两个相异的排列a: a[1..M]a[1..M] 和 b[1..M]b[1..M],我们称 aa 比 bb 小当且仅当 存在一个 ii,满足对于所有小于 ii 的 jj 都有 a_j = b_jaj=bj 且 a_i < b_iai<bi

    Input

    有多组询问,第一行包含一个正整数 TT 代表有几组询问。

    每组询问的第一行包含两个正整数 N, MN,M,分别代表度熊丢进机器的字符串数目以及参数的长度。接下来还有 2 imes N2×N 行,每行有一个长度为 MM 的字符串,当中的第 2 imes i - 12×i1 行的字符串代表度熊丢进去机器的第 ii 个字符串,而第 2 imes i2×i 行的字符串代表机器对于第 ii 个字符串的输出结果。

    • 1 le T le 1001T100

    • 1 le N le 201N20

    • 1 le M le 501M50

    • 字符串由英文小写字母('a' 至 'z') 组成

    Output

    对于每一个询问,输出一行,若不存在任何参数满足度熊的记录,这行只包含一个整数 -11。否则这行包含一个排列,代表此机器所有可能的参数中字典序最小的那个。

    Sample Input
    4
    1 3
    abc
    bca
    2 4
    aaab
    baaa
    cdcc
    cccd
    3 3
    aaa
    aaa
    bbb
    bbb
    ccc
    ccc
    1 1
    a
    z
    Sample Output
    3 1 2 2 4 3 1 1 2 3 -1  
    3 1 2
    2 4 3 1
    1 2 3
    -1
    
    Note
    第一组询问中, p[1]=3,p[2]=1,p[3]=2p[1]=3,p[2]=1,p[3]=2 是唯一的机器可能的参数。
    
    第二组询问中, p=[2,4,3,1]p=[2,4,3,1] 和 p=[3,4,2,1]p=[3,4,2,1] 都是机器可能的参数,不过 [2,4,3,1][2,4,3,1] 的字典序比 [3,4,2,1][3,4,2,1] 还小,故必须输出 2,4,3,1。 
     

    思路:

    • 观察发现,在序列sv中的第i项数字确定后,原字符串的第i项必然是新字符串的sv[i]项
    • 从1到M逐步构造序列的每一项,如果有字符串不匹配,则从小到大更新的构造sv[i]
    • 当sv[i]无法更新时说明没有一个可以匹配到所有字符串的序列,此时返回-1
    • 当sv[1~M]都更新完成,打印sv数组即为答案

    代码如下:

    //1002
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    
    char pre[25][55];
    char nxt[25][55];
    int v[55],sv[55];
    int N,M;
    int j,k ;
    char c;
    bool bfs(int i) {
        if(i == M)return true;
        c = pre[0][i];
        for(j = 0 ; j < M; j++){
            if(c == nxt[0][j] && v[j] == -1){
                v[j] = i; sv[i] = j;
                
                for(k = 1; k < N;k++){            
                    if(pre[k][i] != nxt[k][sv[i]]){
                        v[j] = -1;sv[i] = -1;
                        break;
                    };
                }
                if(k != N)continue;
                if(bfs(i+1))return true;
            }
        }
        return false;
    }
    int main(){
        int T;
        scanf("%d",&T);
        while(T--){
            scanf("%d%d",&N,&M);
            for(int i = 0 ; i < N;i++){
                scanf("%s",pre[i]) ;
                scanf("%s",nxt[i]) ;
            }
            memset(v,-1,sizeof(v));
            if(bfs(0)){
                for(int i = 0 ; i < M;i++){
                    printf("%d",sv[i]+1);
                    if(i == M-1) printf("
    ");
                    else printf(" ");
                }
            }else{
                printf("-1
    ");
            }
        }
        return 0;
    }
  • 相关阅读:
    2017年度最具商业价值人工智能公司TOP50 榜单发布
    滑动swipe的妙用
    UE3优化
    UE4 框架
    制作HUD
    Component概念
    手游记事
    C++与UnrealScript脚本交互
    unreal Script(US)一些注意事项
    UDK游戏打包详解
  • 原文地址:https://www.cnblogs.com/zhangxiaomao/p/11374252.html
Copyright © 2011-2022 走看看