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

HDU 1015Safecracker(算是很简单的dfs了,却debug了很久很久)

2013年11月01日 ⁄ 综合 ⁄ 共 3489字 ⁄ 字号 评论关闭

Safecracker

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


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
 
题目大意:意思很简单在字符串中找五个字符可以满足上面的式子。存在多组,输出字典序最大的,没有的话,输出no solution。

          解题思路:很简单的dfs。但在调试的时候,却发现用pow有误差,125+6竟然得到了130。还是pow(double,double)靠谱。开始是一步步sum判断的,不知道怎么反正老是出错,最后狠下心来直接用个debug每次直接算五个。果断1A。

          题目地址:Safecracker

AC代码:
#include<iostream>
#include<string>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
int tar,len;
char a[20];  //题目中说的5~12个字母
double b[20];  //转化为1~26
int visi[20];
char res[10];
char tmp[10];

int debug(char *s)  //算sum
{
    int i;
    double sum=0;
    for(i=0;i<5;i+=2)
    {
        sum+=pow(double(s[i]-'A'+1),double(i+1));
    }
    for(i=1;i<5;i+=2)
    {
        sum-=pow(double(s[i]-'A'+1),double(i+1));
    }
    return sum;
}

void dfs(int step)
{
    int i;
    if(step==5)
    {
        tmp[5]='\0';
        if(debug(tmp)==tar)
        {
             if(strcmp(tmp,res)>0)
                 strcpy(res,tmp);
        }
        return;
    }
    for(i=0;i<len;i++)
    {
       if(!visi[i])
       {
           tmp[step]=a[i];
           visi[i]=1;
           //if(step%2==1) sum-=pow(b[i],double(step+1));  一步步判断有错误
           //else sum+=pow(b[i],double(step+1));
           dfs(step+1);
           visi[i]=0;
       }
    }
}

int main()
{
    int i;

    //char p[10]="YOXUZ";
    //cout<<debug(p)<<endl;
    while(scanf("%d%s",&tar,a))
    {
        if(tar==0&&strcmp(a,"END")==0)
            break;
        memset(visi,0,sizeof(visi));
        strcpy(res,"@");  //初始化res;
        len=strlen(a);

        for(i=0;i<len;i++)
            b[i]=a[i]-'A'+1;

        for(i=0;i<len;i++)
        {
            visi[i]=1;
            tmp[0]=a[i];
            dfs(1);
            visi[i]=0;  //回溯
        }
        if(strcmp(res,"@")==0)
            puts("no solution");
        else
            cout<<res<<endl;
    }
    return 0;
}

//281MS 300K

抱歉!评论已关闭.