HDU 1111 Secret Code 深搜

题意:告诉你两个复数k=a+bi和k‘=c+di,给你一个等式:k=a[0]+a[1]*k'^1+a[2]*k'^2+...+a[n]*k'^n。其中0<=a[i]<|k'|,然后递归不会超过100层。求a[0...n],逆序输出。


想法:枚举a[0]~a[n],当我知道a[k]的时候,我会消除这个已知量,则k-a[k]=a[k+1]*k'...a[n]*k'^(n-k),则(k-a[k])/k',一次进行。

解析:当k=0时,k-a[0]=a[1]*k'^1+a[2]*k'^2+...+a[n]*k'^n,两边同时除以k’得到

       (k-a[0])/k'=a[1]+a[2]*k'^1+...+a[n]*k'^(n-1);

       *****这里还用k表示新值*****

       当k=1时,k-a[1]=a[1]+a[2]*k'^1+...+a[n]*k'^(n-1),两边同时除以k‘得到

       (k-a[1])/k'=a[2]+a[3]*k'^1+...+a[n]*k'^(n-2);

       .........

其实这就是一个递归的过程,模拟就好了。


#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
__int64 xr,xi,br,bi;
__int64 ans[1000],nomark;
__int64 t;
void dfs(__int64 Xr,__int64 Xi,__int64 dep)
{
	if(dep>100) return;
	if(!nomark) return;
	if(Xr==0&&Xi==0)
	{
		for(__int64 i=dep-1;i>=1;i--)
		{
			if(i==dep-1) printf("%I64d",ans[i]);
			else printf(",%I64d",ans[i]);
		}
		cout<<endl;
		nomark=0;
		return;
	}
	for(__int64 i=0;i*i<br*br+bi*bi;i++)
	{
		ans[dep]=i;
		__int64 p1=(Xr-i)*br+Xi*bi;
		__int64 p2=Xi*br-(Xr-i)*bi;
		if(p1%t==0&&p2%t==0)
		{
			dfs(p1/t,p2/t,dep+1);
		}
		if(!nomark) return;
	}
}
void treatment()
{
	nomark=1;
	t=br*br+bi*bi;
	dfs(xr,xi,1); 
	if(nomark) printf("The code cannot be decrypted.\n");
}
int main()
{
	__int64 t;
	scanf("%I64d",&t);
	while(t--)
	{
		scanf("%I64d%I64d%I64d%I64d",&xr,&xi,&br,&bi);
		if(xr==0&&xi==0) //这个特判是我递归的缺陷,可以在递归里改动,这个可不写
		{
			printf("0\n");
			continue;
		}
		treatment();
	}
	return 0;
}





你可能感兴趣的:(HDU 1111 Secret Code 深搜)