题意:给定复数x和复数b,求序列ai使得x=a0+a1*b+a2*b^2+...an*b^n。其中n<=100,|b|>ai>=0,|b|>1.
题解:先要知道复数的运算方法,复数的模:|Z|=|a+bi|=sqrt(a*a+b*b);复数除法:令t=c*c+d*d,(a+bi)/(c+di)=(ac+bd)/t+(bc-ad)/ti。接着就是化简公式了X=a0+(a1+(a2+...)*b)*b。深搜枚举a0~an,每次减去ai之后除以b后,剩下的就又有一个常数,直到0为止。除法的时候,由于要保证整除(就是上面的ac+bd和bc-ad是t的倍数),可以减少很多时间。数据有点大,用64位__int64。
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
typedef __int64 LL;
const int maxn=110;
LL xr,xi,br,bi,num;
LL flag,t;
LL ans[maxn];//保存枚举的ai
void dfs(LL rr,LL ii,LL step)
{
LL x,y,i;
if (step>100)return;
if(flag)return;
if(rr==0&&ii==0)
{
flag=1;
t=step;
return;
}
for(i=0;i*i<num;i++)
{
//复数除法运算
x=(rr-i)*br+ii*bi;
y=ii*br-(rr-i)*bi;
ans[step]=i;
if(x%num==0&&y%num==0)//保证整除
dfs(x/num,y/num,step+1);
if(flag)return;
}
}
int main()
{
LL T,i;
scanf("%I64d",&T);
while(T--)
{
scanf("%I64d%I64d%I64d%I64d",&xr,&xi,&br,&bi);
num=br*br+bi*bi;
flag=0;
dfs(xr,xi,0);
if(!flag)printf("The code cannot be decrypted.\n");
else
{
printf("%I64d",ans[t-1]);
for(i=t-2;i>=0;i--)
printf(",%I64d",ans[i]);
printf("\n");
}
}
return 0;
}