杭电OJ 1015 Safecracker

来源:互联网 发布:小米网络音响app连不上 编辑:程序博客网 时间:2024/05/16 01:27

Safecracker

Problem Description

=== Op techbriefing, 2002/11/02 06:42 CST === 
"The item is locked in a Klein safe behind a painting in the second-floorlibrary. Klein safes are extremely rare; most of them, along with Klein and hisfactory, were destroyed in World War II. Fortunately old Brumbaugh fromresearch knew Klein's secrets and wrote them down before he died. A Klein safehas two distinguishing features: a combination lock that uses letters insteadof numbers, and an engraved quotation on the door. A Klein quotation alwayscontains between five and twelve distinct uppercase letters, usually at thebeginning of sentences, and mentions one or more numbers. Five of the uppercaseletters form the combination that opens the safe. By combining the digits fromall the numbers in the appropriate way you get a numeric target. (The detailsof constructing the target number are classified.) To find the combination youmust select five letters v, w, x, y, and z that satisfy the following equation,where each letter is replaced by its ordinal position in the alphabet (A=1,B=2, ..., Z=26). The combination is then vwxyz. If there is more than onesolution then the combination is the one that is lexicographically greatest,i.e., the one that would appear last in a dictionary." 

v - w^2 + x^3 - y^4 + z^5 = target 

"For example, given target 1 and letter set ABCDEFGHIJKL, one possiblesolution is FIECB, since 6 - 9^2 + 5^3 - 3^4 + 2^5 = 1. There are actuallyseveral solutions in this case, and the combination turns out to be LKEBA.Klein thought it was safe to encode the combination within the engraving,because it could take months of effort to try all the possibilities even if youknew the secret. But of course computers didn't exist then." 

=== Op tech directive, computer division, 2002/11/02 12:30 CST === 

"Develop a program to find Klein combinations in preparation for fielddeployment. Use standard test methodology as per departmental regulations.Input consists of one or more lines containing a positive integer target lessthan twelve million, a space, then at least five and at most twelve distinctuppercase letters. The last line will contain a target of zero and the lettersEND; this signals the end of the input. For each line output the Kleincombination, break ties with lexicographic order, or 'no solution' if there isno correct combination. Use the exact format shown below."

 

 

Sample Input

1 ABCDEFGHIJKL

11700519ZAYEXIWOVU

3072997 SOUGHT

1234567THEQUICKFROG

0 END

 

 

Sample Output

LKEBA

YOXUZ

GHOST

no solution

 

解题心得:

         通过穷举可以轻松AC,本来这道题是想用5个for循环暴力求解(毕竟是水题),不过最近刚好学习了深度优先搜索,就用dfs了,也没啥好说的,关键是通过一个变量flag来控制dfs的输出,保证只把字典序最大的字符串输出(当然,之前要先有大到小排序),而不是输出所有可能的情况。

         因为是水题,所以时间肯定够,还用不着更高级的搜索技巧(反正我还不会【偷笑】),就当检验初学dfs的成果吧。

最近还学了如何通过重定向的方式用文件输入输出(从这回贴出的代码就看得出来),在测试数据时还挺方便的,据说经验丰富的选手很会使用条件编译,又学了一招,不错不错。

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <math.h>#define SIZE 20//#define LOCALchar ch[SIZE], ans[SIZE];int num[SIZE], book[SIZE];int flag, target, len, sum;int cmp(const void *a, const void *b);void dfs(int step);int main(){#ifdef LOCAL    freopen("data.in", "r", stdin);    freopen("data.out", "w", stdout);#endifint i;while (scanf("%d %s", &target, ch) != EOF && target) {flag = 0;memset(book, 0, sizeof(book));len = strlen(ch);qsort(ch, len, sizeof(ch[0]), cmp);dfs(0);if (flag == 0) printf("no solution\n");}return 0;}int cmp(const void *a, const void *b){return *(char *)b - *(char *)a;}void dfs(int step){int i;if (flag) return;if (step > 4) {sum = num[0] - num[1]*num[1] + num[2]*num[2]*num[2]- num[3]*num[3]*num[3]*num[3] + num[4]*num[4]*num[4]*num[4]*num[4];if (sum == target) {flag = 1;for (i = 0; i < 5; i++)printf("%c", ans[i]);printf("\n");}return;}for (i = 0; i < len; i++) {if (book[i] == 0) {book[i] = 1;ans[step] = ch[i];num[step] = ans[step] - 'A' + 1;dfs(step+1);book[i] = 0;}}return;}


0 0
原创粉丝点击