Sicily 1213. 打开遗迹之门

来源:互联网 发布:淘宝国际下载安装 编辑:程序博客网 时间:2024/04/27 19:50

1213. 打开遗迹之门

Constraints

Time Limit: 1 secs, Memory Limit: 32 MB

Description

NightElf是一个古老的种族,在他们的遗迹上到处都有古NightElf的奇妙文字,这些文字都是一些十分美妙而复杂的符号。然而,现在的NightElf人早已不认识古文字了,因为古文字过于复杂,早在几十个世纪之前,他们就改用简单的英文字母来代替古代的文字符号,每个古文字符号对应一个英文字母。当然,正是因为对应关系渐渐的被人遗忘了,所以古代文字已经无法卒读了。除了这一点之外,古语同现代语没有任何区别。

有一天,探险家Arthas在一个古老的NightElf遗迹前面被一扇大门给拦住了。大门上用古NightElf文字刻着一句话。当地人告诉他,只有知道这句话的意思,解出一个谜题,才能进入这个遗迹。
于是,Arthas下决心要找出古文字和现代的英文字母之间的联系,理解出这句话的含义。然而这并不是一件轻松的工作。所幸,他的一个朋友是语言学家,告诉了他一些很重要的事实:
NightElf文字共有n(1<=n<=27)个字母。其中n-1个文字是有意义的,这n-1个文字在现代语中用小写英文字母a,b,c.....中的前n-1个表示。还有一个文字是分隔符。在句子中每两个单词之间有且只有一个分隔符,将单词隔开。另外,NightElf语言中每个单词有着非常丰富的意思,因此只有很少的单词。

当然,遗迹大门上的那一句话中的每个单词都应该是NightElf语言中的合法单词。于是Arthas便想通过了解NightElf语言中的所有单词,来试着找出句子的含义。

Input

第一行一个整数t,表示有t组数据。
每组数据第一行是两个整数n(1=<n<=27)和m(1=<m<=200),分别表示NightElf语言的字符数和句子的字符数。
接着一行有m个整数,每个整数都在1到n之间,且1到n中的每一个数都会出现。每个数代表一个古NightElf语言的文字符号,相同的数字表示相同的文字符号。
再来是一个整数q(1=<q<=200),表示NightElf语言的单词数。
接下来有q行,每行一个由现代语写出的(即用小写英文字母表示)单词。每个单词的长度不超过10。

Output

输出只有一行,是Arthas该句子分析的结果:
  如果句子只有唯一的可能,将它翻译成现代语输出
  如果没有任何可能的单词组合组成句子,输出No solution
  如果句子有多种可能的组合,输出Cannot determine

Sample Input

15 183 2 1 3 5 4 2 1 1 5 2 4 3 4 5 3 4 114adcabacbcaccadbacabbbdccdaccbaaadbabacbcdabacbaabcdcb

Sample Output

adca bdcc dbab abc

Problem Source

ZSUACM Team Member

// Problem#: 1213// Submission#: 3586094// The source code is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License// URI: http://creativecommons.org/licenses/by-nc-sa/3.0/// All Copyright reserved by Informatic Lab of Sun Yat-sen University#include <stdio.h>#include <string.h>int n, m, q;char num2str[30];char words[205][11];int wl[205];char senChar[205];int senNum[205];int deli;bool wordLength[11];int answerNum;bool anAns;char ansNum2str[30];int w[205][2];int wn;bool check() {    int sp = 0;    wn = 0;    if (senNum[0] == deli || senNum[m - 1] == deli) return false;    for (int i = 0; i < m; i++) {        if (senNum[i] == deli) {            if (!wordLength[i - sp]) return false;            w[wn][0] = sp;            w[wn][1] = i - 1;            wn++;            sp = i + 1;        }    }    if (!wordLength[m - sp]) return false;    w[wn][0] = sp;    w[wn][1] = m - 1;    wn++;    return true;}bool isOK(int numNow, int charNow) {        bool existChar[30];    memset(existChar, false, sizeof(existChar));    for (int i = 1; i <= n; i++) if (num2str[i] != '\0') existChar[num2str[i] - 'a'] = true;    for (int i = 0; i < wl[charNow]; i++) {        if (!((num2str[senNum[w[numNow][0] + i]] == '\0' && !existChar[words[charNow][i] - 'a']) || num2str[senNum[w[numNow][0] + i]] == words[charNow][i])) return false;    }    return true;    }bool isOK2() {    int charNum[30];    memset(charNum, 0, sizeof(charNum));    for (int i = 1; i <= n; i++) if (num2str[i] != '\0') charNum[num2str[i] - 'a']++;    for (int i = 0; i < 30; i++) if (charNum[i] > 1) return false;    return true;}void DFS(int now) {    if (now == wn) {        for (int i = 0; i < 30; i++) ansNum2str[i] = num2str[i];        answerNum++;        return;    }    int nowLength = w[now][1] - w[now][0] + 1;    for (int i = 0; i < q; i++) {        if (wl[i] == nowLength && isOK(now, i)) {            char lastNum2str[30];            for (int j = 1; j <= n; j++) lastNum2str[j] = num2str[j];            for (int j = 0; j < wl[i]; j++) num2str[senNum[w[now][0] + j]] = words[i][j];            if (!isOK2()) {                for (int j = 1; j <= n; j++) num2str[j] = lastNum2str[j];                continue;            }            DFS(now + 1);            for (int j = 1; j <= n; j++) num2str[j] = lastNum2str[j];        }    }}int main() {    int caseNum;    scanf("%d", &caseNum);    while (caseNum--) {        scanf("%d%d", &n, &m);        for (int i = 0; i < m; i++) scanf("%d", senNum + i);        scanf("%d", &q);        memset(wordLength, false, sizeof(wordLength));        for (int i = 0; i < q; i++) {            scanf("%s", words[i]);            wl[i] = strlen(words[i]);            wordLength[wl[i]] = true;        }        answerNum = 0;        for (int i = 1; i <= n; i++) {            deli = i;            if (check()) {                memset(num2str, 0, sizeof(num2str));                anAns = false;                DFS(0);                if (answerNum >= 2) break;            }        }        if(answerNum == 0) printf("No solution\n");        else if (answerNum >= 2) printf("Cannot determine\n");        else {            for (int i = 0; i < m; i++) {                if (ansNum2str[senNum[i]] == '\0') printf(" ");                else printf("%c", ansNum2str[senNum[i]]);            }            printf("\n");        }    }    return 0;}                                 


0 0
原创粉丝点击