HDU 1111 Secret Code DFS 解题报告

博客探讨了HDU 1111 Secret Code问题,该问题涉及复数运算和深度优先搜索(DFS)。博主解释了题目含义的困惑,并提出通过DFS解决数列求解问题。在递归过程中,博主展示了如何计算并简化表达式,最终实现AC的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Secret Code

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


Problem Description
The Sarcophagus itself is locked by a secret numerical code. When somebody wants to open it, he must know the code and set it exactly on the top of the Sarcophagus. A very intricate mechanism then opens the cover. If an incorrect code is entered, the tickets inside would catch fire immediately and they would have been lost forever. The code (consisting of up to 100 integers) was hidden in the Alexandrian Library but unfortunately, as you probably know, the library burned down completely. 

But an almost unknown archaeologist has obtained a copy of the code something during the 18th century. He was afraid that the code could get to the ``wrong people'' so he has encoded the numbers in a very special way. He took a random complex number B that was greater (in absolute value) than any of the encoded numbers. Then he counted the numbers as the digits of the system with basis B. That means the sequence of numbers an, an-1, ..., a1, a0 was encoded as the number X = a0 + a1B + a2B2 + ...+ anBn. 

Your goal is to decrypt the secret code, i.e. to express a given number X in the number system to the base B. In other words, given the numbers X and Byou are to determine the ``digit'' a0 through an. 
 

Input
The input consists of T test cases. The number of them (T) is given on the first line of the input file. Each test case consists of one single line containing four integer numbers Xr, Xi, Br, Bi (|Xr|,|Xi| <= 1000000, |Br|,|Bi| <= 16). These numbers indicate the real and complex components of numbers X and B, i.e. X = Xr + i.Xi, B = Br + i.Bi. B is the basis of the system (|B| > 1), X is the number you have to express. 
 

Output
Your program must output a single line for each test case. The line should contain the ``digits'' an, an-1, ..., a1, a0, separated by commas. The following conditions must be satisfied: 
for all i in {0, 1, 2, ...n}: 0 <= ai < |B| 
X = a0 + a1B + a2B2 + ...+ anBn 
if n > 0 then an <> 0 
n <= 100 
If there are no numbers meeting these criteria, output the sentence "The code cannot be decrypted.". If there are more possibilities, print any of them. 
 

Sample Input
  
4 -935 2475 -11 -15 1 0 -3 -2 93 16 3 2 191 -192 11 -12
 

Sample Output
  
8,11,18 1 The code cannot be decrypted. 16,15
 

Source

题目大意:

输入一个复数X=xr+xi以及复数B=br+bi,求数列a[n]使得x=a0+a1*b+a2*b^2+...an*b^n。其中|Xi| <= 1000000, |Bi| <= 16,n<=100,

|b|>ai>=0,|b|>1.

这道题可谓是晦涩难懂啊,理解了好长时间都没搞懂不过是什么意思,每个单词你都认识,放到题中却不能明白它的含义,真让人捉急啊。

好了,废话不多说,直接讲思路。明白了题意,明白人第一个想法就是搜索,个人觉得,搜索有时候就等价于枚举,也就是暴力,只是在

枚举的过程中采取了一定的手段,这样的手段被大家分为了两类,一类就是按照广度优先的原则,就是我们通常所说的BFS;另一类就是按

照深度优先的原则,也就是今天我们采用的DFS.当然,所谓的“剪枝”也是必不可少的。在本题中,由于a[n]的个数是0~100,所以,我们按照

“深度优先”的原则,即可迎刃而解。那么,如何DFS呢?我们知道x=a0+a1*b+a2*b^2+...an*b^n,通过化简,我们得到:

x=a0+(a1+(a2+(a3+...)*b)*b)*b,每次我们向前搜索一次,减掉一个a[i],剩下的就是m+ni,其中m=(xr-i)*br+xi*bi;n=xi*br-(xr-i)*bi;如此递归往复

胜利的曙光已经点亮了天边的云彩!

特别说明:

该源代码亲测,在HDOJ下用G++提交TL,用C++提交750ms,AC!

源代码:

#include <iostream>

using namespace std;

int xr,xi,br,bi,con;
int flag,t;
int a[105];  //保存枚举的ai
void dfs(int n)
{
    int x,y,i;
    if(n>100) return;
    if(xr==0&&xi==0)
    {
        flag=1;
        t=n;
        return;
    }
    for(i=0;i*i<con;i++)
    {
        //X减去a[i]后剩下的部分,根据复数的除法运算可以得到如下表达式,X=x+yi
        x=(xr-i)*br+xi*bi;
        y=xi*br-(xr-i)*bi;
        a[n]=i;
        if(x%con==0&&y%con==0) //保证整除
        {
            xr=x/con;
            xi=y/con;
            dfs(n+1);
        }
        if(flag) return;
    }
}

int main()
{
    int T;
    cin>>T;
    while(T--)
    {
        cin>>xr>>xi>>br>>bi;
        con=br*br+bi*bi;
        flag=0;
        dfs(0);
        if(!flag)
            cout<<"The code cannot be decrypted."<<endl;
        else
        {
            cout<<a[t-1];
            for(int i=t-2;i>=0;i--)
                cout<<','<<a[i];
            cout<<endl;
        }
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值