CodeVS 1416|USACO Train 5.5.3|Two Five|二五语言|搜索

来源:互联网 发布:邮箱管理软件 mac 编辑:程序博客网 时间:2024/05/16 09:31

题目

【描述】

有一种奇怪的语言叫做“贰五语言”。它的每个单词都由A~Y这25个字母各一个组成。但是,并不是任何一种排列都是一个合法的贰五语言单词。贰五语言的单词必须满足这样一个条件:把它的25个字母排成一个5*5的矩阵,它的每一行和每一列都必须是递增的。比如单词ACEPTBDHQUFJMRWGKNSXILOVY,它排成的矩阵如下所示:
A C E P T
B D H Q U
F J M R W
G K N S X
I L O V Y

因为它的每行每列都是递增的,所以它是一个合法的单词。而单词YXWVUTSRQPONMLKJIHGFEDCBA则显然不合法。 由于单词太长存储不便,需要给每一个单词编一个码。编码方法如下:从左到右,再从上倒下,可以由一个矩阵的得到一个单词,再把单词按照字典顺序排序。比如,单词ABCDEFGHIJKLMNOPQRSTUVWXY的编码为1,而单词ABCDEFGHIJKLMNOPQRSUTVWXY的编码为2。
现在,你需要编一个程序,完成单词与编码间的转换。

【INPUT FORMAT】

第一行为一个字母N或W。N表示把编码转换为单词,W表示把单词转换为编码。 若第一行为N,则第二行为一个整数,表示单词的编码。若第一行为W,则第二行为一个合法的单词。

【OUTPUT FORMAT:】

(file twofive.out)
每行一个整数或单词。

【SAMPLE INPUT】

INPUT1

N
2

INPUT2

W
ABCDEFGHIJKLMNOPQRSUTVWXY

【SAMPLE OUTPUT】

OUTPUT 1

ABCDEFGHIJKLMNOPQRSUTVWXY

OUTPUT 2

2

题解

一个简单的暴力搜索题
毕竟是Train的

由于要求每格比上和左都要大,因此考虑在填字母的时候,从小到大填,每行结尾添加,而且要比上一行填的少,即可。

#include <cstdio>#include <cstring>#define FOR(i,j,k) for(i=j;i<=k;++i)const int MAX = 7776;int l[6], d[MAX], s[32], x[26], y[26];int dfs(char c) {    int sta = 0, i;    FOR(i,1,5) sta = sta * 6 + l[i];    int &ans = d[sta];    if (ans == -1) {        ans = 0;        if (!x[c]) {            FOR(i,1,5) if (l[i] < l[i - 1]) {                ++l[i];                ans += dfs(c + 1);                --l[i];            }        } else if (l[x[c]] < l[x[c] - 1] && l[x[c]] + 1 == y[c]) {            ++l[x[c]];            ans += dfs(c + 1);            --l[x[c]];        }    }    return ans;}int compute() {    memset(l, 0, sizeof l);    memset(d, -1, sizeof d);    l[0] = 5; d[MAX - 1] = 1;    return dfs(0);}int main() {    int n = 1, t, i, j;    char k, c;    scanf("%c\n", &c);    if (c == 'N') {        scanf("%d", &n);        FOR(i,1,5) FOR(j,1,5) FOR(c,0,24) if (!x[c]) {            x[c] = i; y[c] = j;            t = compute();            if (n > t) n -= t; else break;            x[c] = y[c] = 0;        }        FOR(c,0,24) s[(x[c] - 1) * 5 + y[c]] = c + 'A';        FOR(i,1,25) putchar(s[i]);        putchar('\n');    } else {        FOR(i,1,5) FOR(j,1,5) {            c = getchar() - 'A';            FOR(k,0,c-1) if (!x[k]) {                x[k] = i; y[k] = j;                n += compute();                x[k] = y[k] = 0;            }            x[c] = i; y[c] = j;        }        printf("%d\n", n);    }}
0 0
原创粉丝点击