HDU 1111 Secret Code(数论的dfs)

Secret Code
Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u
Submit Status

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
 
题目意思:
输入一个复数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.
 
分析:
参考了一下别人的思路:
  • 暴力搜索,把要搜索的序列{an}想成一个森林,a0在第一层,a1在下一层,以此类推
  • 秦九韶算法:x=a0+(a1+(a2+(a3+…)*b)*b)*b,容易想到递归实现
  • 为了方便运算,把实部、虚部拆开一起递归,每次递归枚举下一层a(i+1)的所有可能结果,很容易想到{an}必定都为整数序列,每枚举一个a(i+1),判断[X-a(i)]%b能否整除(实部与实部、虚部与虚部),满足继续dfs,不满足继续枚举,直到Xr==0,Xi==0递归结束,当然不能超过100层。最后得到的序列逆序输出即可

看了大佬的思路才懂。。。。

code:

#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<queue>
#include<set>
#include<map>
#include<string>
#include<memory.h>
using namespace std;
int xr,xi,br,bi,con;
int flag,t;
int a[105];
void dfs(int n)
{
    int x,y,i;
    if(n>100)//多项式最多00项
        return ;
    if(xr==0&&xi==0)
    {
        flag=1;
        t=n;
        return ;
    }
    for(i=0;i*i<con;i++)
    {
        //xi减去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;
}
原文地址:https://www.cnblogs.com/yinbiao/p/9355955.html