2014/12/6
好好写一次。
因为学的很透彻。。因为学的很艰难。。因为这道题目我不会,是因为我丢掉了以前高中,初中时代那种思维。
现在只会看片玩游戏。脑子真的变笨了。
如题目要求
a0+a1t+a2t^2+...=a
a0+a1a+a2a^2+...=b
移项得
a1+a2t + a3t^2+... =(a-a0)/t
a1+a2a + a3a^2+...=(b-a0) /a
(a-a0) %t ==0 a0 = A%t; a0 <= b,a0<= a
(b-a0)%a==0 a0 = B%a;
设 (a-a0)/t 为A ,(b-a0)/a 为 B 。当 A== B时满足条件。即有ai满足两式均成立。
那么下一个递推式 : a2 + a3t + a4t^2 + ..... = (A- a1)/t;
a2 + a3ta+ a4a^2 + ..... = (B- a1)/t;
根据两个等式我们可知
如果两式求出的ai不相等...并且都不为零,那么可知满足这两个等式成立的条件不存在。即不符合题意。则不存在 f(t)=a,f(a)=b;
还有种情况,就是两式求出ai 不相等,但是至少有一个为0,这种情况下你不能判断它无解,需要继续递归下去。原因:
(A-ai) %t ==0 ai = A%t; if'(A%t == 0&& ai = t) 从 ai = A%t 得出 ai =0;
(B-ai)%a==0 ai = B%a; 而由ai = B%a 得出ai = t;要避免把这种情况也判做无解的处境。
这样子还不够,当 t等于1的时候,任何数 % 1 == 0.这种情况需要特判下。官方题解说明的这种情况官方题解
#include<stdio.h>
#include<string.h>
#define inf 0xff
int find(__int64 t,__int64 a, __int64 A,__int64 B)
{
if(A == B)return 1;
__int64 a0;
__int64 ra ,rb;
ra = A%t;
rb = B%a;
if(ra != rb&&rb != 0&&ra != 0)return 0;
a0 = ra==0?rb:ra;
return find(t,a,(A-a0)/t,(B-a0)/a);
}
int main()
{
int n;
__int64 t,a,b;
while(~scanf("%I64d%I64d%I64d",&t,&a,&b))
{
int ans = 0;
if(a == t&&a == b)
{
if(a == 1)ans=inf;
else ans=2;
}
if(a != t&&(a-b)%(t-a)==0&&(a-b)/(t-a)>=0&&find(t,a,a,b))ans = 1;
if(ans == inf)printf("inf\n");
else printf("%d\n",ans);
}
return 0;
}
第二种方法:
(A-ai)%t==0 ,(B-ai)%a==0.
ai = ai%A = B%a;
如此可求得 ai = B%a;然后反推证明满足条件的ai是否存在: if(ai != 0 && ( A - ai)%t ) return 0;
(当然,前面说过,你要避免a0 = a, ai = B%a 算出来ai是0的情况判做无解的处境)
#include<stdio.h>
#include<string.h>
#define inf 0xff
int find(__int64 t,__int64 a, __int64 A,__int64 B)
{
if(A == B)return 1;
__int64 a0;
a0 = B%a;
if(a0%t !=0 && a0%t != A%t)return 0;
return find(t,a,(A-a0)/t,(B-a0)/a);
}
int main()
{
int n;
__int64 t,a,b;
while(~scanf("%I64d%I64d%I64d",&t,&a,&b))
{
int ans = 0;
if(a == t&&a == b)
{
if(a == 1)ans=inf;
else ans=2;
}
if(a != t&&(a-b)%(t-a)==0&&(a-b)/(t-a)>=0&&find(t,a,a,b))ans = 1;
if(ans == inf)printf("inf\n");
else printf("%d\n",ans);
}
return 0;
}