A+B |
||
Accepted : 8 | Submit : 77 | |
Time Limit : 1000 MS | Memory Limit : 65536 KB |
题目描述给你三个整数a,b,n。问有多少种只包含a,b的不同序列,使得这个序列的和为n。 例如a=2,b=3,n=7,那么有一种序列:(2+2+3=7,2+3+2=7,3+2+2=7)这三种看作相同,算一种。 例如a=3,b=3,n=6,那么只有一种序列:3+3=6。 例如a=4,b=5,n=7,那么不管a和b怎么排都不会等于7,那么就只有0种序列。 输入多个样例,每个样例占一行,包括3个整数a,b,n。(0< a,b,n <10^9).直到文件结束。 输出每个样例输出一行,一个整数,为a,b所能排出的序列数。 样例输入2 3 7 3 3 6 4 5 7 样例输出1 1 0 |
//a和b不一定要有,fuck!!! #include<iostream> #include<cstdio> #include<cmath> using namespace std; //不用int64就可以A的 __int64 exgcd(__int64 a,__int64 b,__int64 &x,__int64 &y) { if(b==0) { x=1; y=0; return a; } __int64 g=exgcd(b,a%b,x,y); __int64 temp=x; x=y; y=temp-(a/b)*y; return g; } __int64 gcd(__int64 m,__int64 n) { while(n) { __int64 tmp=m%n; m=n; n=tmp; } return m; } __int64 mi(__int64 m,__int64 n) { if(m>n) return n; return m; } __int64 ma(__int64 m,__int64 n) { if(m>n) return m; return n; } int main() { __int64 a,b,s,d; while(~scanf("%I64d%I64d%I64d",&a,&b,&s)) { __int64 x,y; d=gcd(a,b); if(s%d!=0) { puts("0"); continue; } else if(a+b>s) { puts("0"); continue; } else if(a==b) { if(s%a==0) puts("1"); else puts("0"); continue; } a=a/d,b=b/d,s=s/d; __int64 tt=exgcd(a,b,x,y); //现在的x,y是ax+by=1的一个解 x=x*s,y=y*s; //现在的xy是ax+by=s的一个解 __int64 cnt=0; //__int64 s1,s2; //根据x,y的值来判断到底有多少可行解 //因为ax+by=s,所以a(x+nb)+b(y-na)=s也是可行解,所以直接找n的值使得x+nb与y-na都为正数或0即可 //代码写搓了。。 /*if(x<=0&&y>=0) //okok { x=-x; if(x%b==0) s1=x/b; else s1=x/b+1; if(y%a==0) s2=y/a; else s2=y/a; } else if(y<=0&&x>=0) //okok { y=-y; if(y%a==0) s1=y/a; else s1=y/a+1; if(x%b==0) s2=x/b; else s2=x/b; } else if(x>0&&y>0) //ok { s1=-x/b; s2=x/b; s1=ma(s1,-y/a); s2=mi(s2,y/a); } else { puts("0"); continue; }*/ x=x%b; if(x<0) x+=b; y=(s-a*x)/b; //解出a(x+nb)+b(y-na)=s,n=0时候的值 if(y<0) cnt=0; else cnt=y/a+1; printf("%I64d\n",cnt); } return 0; }