input
T 1<=T<=1000
x y
output
有多少个起点可以走n(n>=0)步走到(x,y),只能从(x,y)走到(x,y+lcm(x,y))/(x+lcm(x,y),y)
标准解:从(x,y0)走到(x,y),则设x=ag,y0=bg,g=gcd(x,y0),有y=bg+abg=(a+1)bg,因为a,b互质,a,(a+1)互质,所以a和(a+1)b互质,所以若可以从(x,y0)走到(x,y),有gcd(x,y0)=gcd(x,y),然后将x和y中gcd(x,y)除去之后不断除以(x+1)即可
1 #include <iostream> 2 #include <cstdio> 3 #include <set> 4 #include <algorithm> 5 6 using namespace std; 7 8 typedef long long LL; 9 10 //求最大公约数 11 LL gcd(LL a, LL b) { if(!b) return a; else return gcd(b,a%b); } 12 13 int main() 14 { 15 int t,Case = 0; 16 scanf("%d",&t); 17 while(t--) 18 { 19 LL ex,ey; //终点坐标 20 21 scanf("%lld%lld",&ex,&ey); 22 LL GCD = gcd(ex,ey); 23 ex/=GCD,ey /=GCD; 24 int ans = 0; 25 while(1) 26 { 27 if(ey < ex) swap(ex,ey); 28 ans++; 29 if(ey % (ex+1)) break; 30 ey /= (ex+1); 31 } 32 33 printf("Case #%d: %d\n",++Case,ans); 34 } 35 }
answer
1 #include <cstdio> 2 #include <queue> 3 #include <cstring> 4 #include <iostream> 5 #include <cstdlib> 6 #include <algorithm> 7 #include <vector> 8 #include <map> 9 #include <set> 10 #include <ctime> 11 #include <cmath> 12 #include <cctype> 13 #define MAX 100000 14 #define LL long long 15 int cas=1,T,x,y,d[1000],dn; 16 void find(int x,int *d,int& dn) 17 { 18 dn=-1; 19 int m=sqrt(x); 20 for(int i=1;i<=m;i++) if(x%i==0) d[++dn]=i; 21 for(int i=dn;i>=0;i--) d[++dn]=x/d[i]; 22 } 23 int gcd(int a,int b) { return b==0?a:gcd(b,a%b); } 24 int main() 25 { 26 // freopen("in","r",stdin); 27 scanf("%d",&T); 28 while(T--) 29 { 30 scanf("%d%d",&x,&y); 31 int step=1,flag=1; 32 while(flag&&x!=y) 33 { 34 flag=0; 35 if(x>y) std::swap(x,y); 36 int g=gcd(x,y); 37 find(g,d,dn); 38 for(int i=dn;i>=0;i--) 39 { 40 if(y%(d[i]+x)==0) 41 { 42 int y1=y/(d[i]+x)*d[i]; 43 if(gcd(x,y1)==d[i]) { y=y1;step++;flag=1;break; } 44 } 45 } 46 } 47 printf("Case #%d: %d\n",cas++,step); 48 } 49 //printf("time=%.3lf",(double)clock()/CLOCKS_PER_SEC); 50 return 0; 51 }
My Code
时间: 2024-10-08 18:32:08