数论+dfs+复数除法剪枝 Secret Code hdu1111

X = a0 + a1B + a2B2 + ...+ anBn. (其实是B^2。。。。这个坑人)

满足复数除法的剪枝真的是强大啊

枚举每一个ai, 然后 除复数B, 这里剪枝,判断是否可以整除,复数的除法公式自己推


/*
ID: meixiny1
PROG: test
LANG: C++11
*/
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <climits>
#include <string>
#include <vector>
#include <cmath>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <sstream>
#include <cctype>
using namespace std;
typedef long long ll;
typedef pair<int ,int> pii;
#define MEM(a,b) memset(a,b,sizeof a)
#define CLR(a) memset(a,0,sizeof a);
const int inf = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
#define PI 3.1415926535898
//#define LOCAL
ll limit,ok;
ll xr,xi,c,d;
ll ans;
int dfs(ll xr,ll xi,int deep){
    ll a ,b = xi,x,y;
    int check = 0;
    if(deep>100)return 0;
    if(xi==0 && xr<=limit && ((xr>=0 && deep == 0 ) || (xr>0))){
        ok = 1;
        printf("%lld",xr);
        return 1;
    }
    for(int i=0;i<=limit;i++){
        a =xr - i;
        x = (a*c+d*b)%ans;
        y = (c*b-a*d)%ans;
        if(x || y)continue;
        x=(a*c+d*b)/ans;
        y=(c*b-a*d)/ans;
        check |= dfs(x,y,deep+1);
        if(check){
            printf(",%d",i);
            return 1;
        }
    }
    return 0;
}
int main()
{
#ifdef LOCAL
    freopen("in.txt", "r", stdin);
//    freopen("out.txt","w",stdout);
#endif
    int t;scanf("%d",&t);
    while(t--){
        ok = 0;
        scanf("%lld%lld%lld%lld",&xr,&xi,&c,&d);
        ans = c*c+d*d;
        if(sqrt(ans)==(ll)sqrt(ans))limit = (ll)sqrt(ans)-1;
        else limit = (ll)sqrt(ans);
        dfs(xr,xi,0);
        if(ok)printf("\n");
        else printf("The code cannot be decrypted.\n");
    }
    return 0;
}


你可能感兴趣的:(数论,DFS)