Secret Code
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 462 Accepted Submission(s): 60
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.
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.
4 -935 2475 -11 -15 1 0 -3 -2 93 16 3 2 191 -192 11 -12
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.
这道题可谓是晦涩难懂啊,理解了好长时间都没搞懂不过是什么意思,每个单词你都认识,放到题中却不能明白它的含义,真让人捉急啊。
好了,废话不多说,直接讲思路。明白了题意,明白人第一个想法就是搜索,个人觉得,搜索有时候就等价于枚举,也就是暴力,只是在
枚举的过程中采取了一定的手段,这样的手段被大家分为了两类,一类就是按照广度优先的原则,就是我们通常所说的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;
}