HDOJ1111 Secret Code(数论+DFS)

http://acm.hdu.edu.cn/showproblem.php?pid=1111


声称做不出来就注孤一生。

结果理解题目就用了好久还看了解题报告。。

涉及到一部分复数知识,算法用的是DFS。

想法是把X=a0+a1b+a2b^2+a3b^3+...+anb^n转化成X=a0+(a1+(a2+(...+an*b)...)*b)*b,搜索对象是a0~an,每次减完判断是否能被b整除(暂且这么表达。。) 。这里要用到复数的除法,公式是(a+bi)/(c+di)=(ac+bd)/(c^2+d^2)+i(bc+ad)/(c^2+d^2)。最后,答案是要倒序输出的。。

代码如下:

#include<stdio.h>
#include<string.h>

__int64 xr,xi,br,bi,t,ans[1000],flag,k;
void dfs(__int64 x,__int64 y,__int64 cur)
{
    __int64 a,b,i;
    if(cur>100) return;
    if(flag) return;
    if(x==0&&y==0) {k=cur;flag=1;return;}
    for(i=0;i*i<t;i++)
    {
        ans[cur]=i;
        a=(x-i)*br+y*bi;
        b=y*br-(x-i)*bi;
        if(a%t==0&&b%t==0) dfs(a/t,b/t,cur+1);
        if(flag) return;
    }
}
int main()
{
    __int64 n,i;
    scanf("%I64d",&n);
    while(n--)
    {
        scanf("%I64d%I64d%I64d%I64d",&xr,&xi,&br,&bi);
        t=br*br+bi*bi;flag=0;
        memset(ans,0,sizeof(ans));
        dfs(xr,xi,0);
        if(!flag) printf("The code cannot be decrypted.\n");
        else
        {
            printf("%I64d",ans[k-1]);
            for(i=k-2;i>=0;i--)
                printf(",%I64d",ans[i]);
            printf("\n");
        }
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值