现在的位置: 首页 > 综合 > 正文

HDU1015 Safecracker

2013年09月01日 ⁄ 综合 ⁄ 共 3825字 ⁄ 字号 评论关闭

                                                          
Safecracker

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 6326    Accepted Submission(s): 3159

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
 

Recommend
JGShining

 
解题思路:本题为深度优先搜索算法题目,题目较长,考验ACMer的耐性。其实意思很简单,给你一个数(32位),一串大写字母(12个以内),要你在字母串中找到5个字母使其满足v - w^2 + x^3 - y^4 + z^5 = 数字,其中字母需转换A=1, B=2, ..., Z=2。这个很容易实现,答案有很多组。再看题目,

“is lexicographically greatest, i.e., the one that would appear last in a dictionary."”

这说明,我们要输出的是所有满足要求的答案中,首字母字典序最靠后的那5个字母。这个也不难实现,直接在搜索前把字母按字典序逆序排一遍即可。搜索时,一旦搜索到适合的答案即可结束搜索,输出答案,一组测试数据完成。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n,len;
int num[13];
int flag[13];
int hu[5];
int f;
bool cmp(int x,int y)
{
    return x>y;
}
void dfs(int i)
{
    /*printf("i=%d\n",i);
    for(int j=0;j<len;j++)
        printf("%d ",num[j]);
    printf("\n");
    for(int j=0;j<len;j++)
        printf("%d ",flag[j]);
    printf("\n");
    for(int j=0;j<i;j++)
        printf("%d ",hu[j]);
    printf("\n");*/
    int sum=0;
    if(f)
        return ;
    if(i==5)
    {
        //printf("\n");
       // for(int j=0;j<i;j++)
           // printf("%d ",hu[j]);
        //printf("\n");
        sum=hu[0] - hu[1]*hu[1] + hu[2]*hu[2]*hu[2] - hu[3]*hu[3]*hu[3]*hu[3] + hu[4]*hu[4]*hu[4]*hu[4]*hu[4];
       // printf("-------sum=%d\n",sum);
        if(sum==n)
        {
           // printf("-------------------sum==n\n");
            for(int j=0;j<5;j++)
                printf("%c",hu[j]+'A'-1);
            printf("\n");
            f=1;
        }
        return ;

    }
    for(int j=0;j<len;j++)
    {
        if(!flag[j])
        {
            flag[j]=1;
            hu[i]=num[j];  //存储搜索结果
            dfs(i+1);
            flag[j]=0;
        }
    }
}
int main()
{
    char ch[13];
    while(scanf("%d%s",&n,ch)&&strcmp(ch,"END"))
    {
        f=0;
        memset(flag,0,sizeof(flag));
        len=strlen(ch);
        for(int i=0;i<len;i++)
            num[i]=ch[i]-'A'+1;
        sort(num,num+len,cmp);     //直接排序,以满足题目要求“is lexicographically greatest, i.e., the one that would appear last in a dictionary."”
        dfs(0);
       // for(int i=0;i<len;i++)
           // printf("%d ",num[i]);
        //printf("\n");
        if(!f)
            printf("no solution\n");
    }
}


抱歉!评论已关闭.