Safecracker

Problem Description

 

=== Op tech briefing, 2002/11/02 06:42 CST ===
"The item is locked in a Klein safe behind a painting in the second-floor library. Klein safes are extremely rare; most of them, along with Klein and his factory, were destroyed in World War II. Fortunately old Brumbaugh from research knew Klein's secrets and wrote them down before he died. A Klein safe has two distinguishing features: a combination lock that uses letters instead of numbers, and an engraved quotation on the door. A Klein quotation always contains between five and twelve distinct uppercase letters, usually at the beginning of sentences, and mentions one or more numbers. Five of the uppercase letters form the combination that opens the safe. By combining the digits from all the numbers in the appropriate way you get a numeric target. (The details of constructing the target number are classified.) To find the combination you must 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 one solution 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 possible solution is FIECB, since 6 - 9^2 + 5^3 - 3^4 + 2^5 = 1. There are actually several 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 you knew 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 field deployment. Use standard test methodology as per departmental regulations. Input consists of one or more lines containing a positive integer target less than twelve million, a space, then at least five and at most twelve distinct uppercase letters. The last line will contain a target of zero and the letters END; this signals the end of the input. For each line output the Klein combination, break ties with lexicographic order, or 'no solution' if there is no correct combination. Use the exact format shown below."
 

 

Sample Input
1 ABCDEFGHIJKL 11700519 ZAYEXIWOVU 3072997 SOUGHT 1234567 THEQUICKFROG 0 END
 

 

Sample Output
LKEBA YOXUZ GHOST no solution
 

 

Source

题意:给定长度5-12的字符串,然后给定一个目标值,问字符串是否存在长度为5并且满足式子 v - w^2 + x^3 - y^4 + z^5 = target 的子串,有就输出,没有就输出no solution,如果有多种情况,输出字典序最大的那个。

因为要输出字典序最大的,所以从后往前遍历(j=len-1;j>=0;j--);

DFS执行框图:

以3072997 SOUGHT为例

SOUG---H,T

SOU---H---G,T;SOU---T---G,H;

SO---G---   ......

以深度优先的遍历方法找到一组解,如果遍历所有可能的情况还是没有解则输出“no solution"

 1 #include <iostream>
 2 #include <string.h>
 3 #include <algorithm>
 4 #include <stdlib.h>
 5 using namespace std;
 6 
 7 char ch[100];      //存放目标字符串
 8 int visit[1000];     //用作标记
 9 int flag,len,N;      //flag标记,len长度,N目标值
10 char str[150];          //存放输入的字符串
11 
12 void DFS(int n,int sum)
13 {
14     int j,t;
15 
16     if(flag)      //flag=1返回
17         return;
18 
19     if(sum==N&&n==5){       //找到目标值返回
20         puts(ch);      //输出字符串
21         flag=1;
22         return;
23     }
24     else{
25         for(j=len-1;j>=0;j--){      //从大到小依次查找(从后往前)
26             if(!visit[j]){
27                 visit[j]=1;
28                 t=str[j]-'A'+1;       //A为1,B为2,依次类推
29                 if(n==0){      //第一个字符
30                     ch[n]=str[j];
31                     DFS(n+1,sum+t);
32                 }
33                 else if(n==1){         //第二个字符
34                     ch[n]=str[j];
35                     DFS(n+1,sum-t*t);
36                 }
37                 else if ( n == 2) {       //第三个字符
38                     ch[n] = str[j];
39                     DFS( n + 1,sum + t * t * t);
40                 }
41                 else if ( n == 3) {       //第四个字符
42                     ch[n] = str[j];
43                     DFS (n + 1,sum - t * t * t  *  t) ;
44                 }
45                 else if ( n == 4) {       //第五个字符
46                     ch[n] = str[j];
47                     DFS (n + 1,sum + t * t * t  *  t * t);
48                 }
49                 visit[j]=0;
50             }
51         }
52     }
53 
54 
55 }
56 
57 int main()
58 {
59     int i,j,cnt;
60 
61     while(scanf("%d%s",&N,str)!=EOF){
62         if(N==0&&strcmp(str,"END")==0)
63             break;
64         memset(visit,0,sizeof(visit));
65         len=strlen(str),flag=0;
66         sort(str,str+len);   //对字符串进行排序
67         //puts(str);
68         DFS(0,0);
69         if(!flag)
70             puts("no solution");
71     }
72     return 0;
73 }
View Code

 

 1 /* 简单DFS
 2  * 题意就是给你一个值和一个字符串,然 后从字符串里选取5个字符,带入
 3  * 方程, 求出字典序最大的解
 4  */ 
 5  
 6 #include <stdio.h>
 7 #include <string.h>
 8 #include <stdlib.h>
 9 #include <algorithm>
10 
11 char ch[100];
12 int  visit[1000];
13 int flag, len, N;
14 char str[150];
15 
16 using namespace std;
17 
18 
19 void DFS( int n, int sum)
20 {   
21     int j, t;
22     
23     if (flag)
24         return;
25         
26     if ( sum == N && n == 5) {
27           puts(ch);
28           flag = 1;
29           return ;
30     }
31     else {
32         for(j = len - 1;  j >= 0; j--){
33             if ( !visit[j] ) {
34                 visit[j] = 1;
35             t = str[j] - 'A' + 1;
36             if (n == 0) {
37                 ch[n] = str[j];
38                 DFS(n + 1, sum + t);
39             }
40             else if ( n == 1) {
41                 ch[n] = str[j];
42                 DFS(n + 1, sum - t  * t);
43             }
44             else if ( n == 2) {
45                 ch[n] = str[j];
46                 DFS( n + 1,sum + t * t * t);
47             }
48             else if ( n == 3) {
49                 ch[n] = str[j];
50                 DFS (n + 1,sum - t * t * t  *  t) ;
51             }
52             else if ( n == 4) {
53                 ch[n] = str[j];
54                 DFS (n + 1,sum + t * t * t  *  t * t);
55             }
56             visit[j] = 0;
57              }
58         }
59     }
60 }
61                
62                 
63             
64             
65             
66         
67 
68 int main( )
69 {
70     int  i, j, cnt;
71     
72     while(scanf("%d%s", &N, str) != EOF) {
73         if (N == 0 && strcmp(str, "END") == 0)
74             break;
75         memset(visit, 0, sizeof(visit));
76         len = strlen(str), flag = 0;
77         sort(str, str + len); //先对字符串进行排序 
78         //puts(str);
79         DFS(0,  0);  
80         if ( !flag)
81             puts("no solution");
82     }
83     return 0;
84 }

 

posted @ 2015-11-28 16:45  Wei_java  阅读(259)  评论(0编辑  收藏  举报