标签:style blog http color os io ar art div
sgu 106:
这道题首先让我们解一个线性方程式ax+by=-c,用拓展欧几里得就可以搞定。但是它要求我们需要输出满足x1<=x<=x2,y1<=y<=y2的解的个数,这可就没那么简单了...
我一开始想记录x和y的边界值,但想了好久,分了n多种情况...因为太繁琐,最后索性放弃分情况,交了一发WA了。
看了某人的解题报告后,发现原来可以求满足x1<=x0+k*r1<=x2,y1<=y0-k*r2<=y2的k的个数。r1=lcm/a,r2=lcm/b,lcm=a*b*gcd(a,b)。
然后解解方程,算算区间相交长度就行了。
(ceil和floor函数要#include <cmath>,而cmath里有名字叫y1的函数,真蛋疼。不过其实只要把y1从全局拿到main函数内部就好)
1 #include <iostream> 2 #include <cstdio> 3 #include <cmath> 4 #define debug(x) cout<<#x<<" = "<<x<<endl 5 using namespace std; 6 typedef long long LL; 7 8 LL gcd(LL a,LL b) 9 { 10 LL temp; 11 if (a<0) a=-a; if (b<0) b=-b; 12 while (b!=0) { temp=b; b=a%b; a=temp; } 13 return a; 14 } 15 //传入的a,b要保证是互质的(因为最后a*1+b*0=1时要保证a为1) 16 void _gcd(LL a,LL b,LL &x,LL &y) 17 { 18 if (b==0) { x=1,y=0; return; } 19 _gcd(b,a%b,x,y); 20 LL temp=y; 21 y=x-a/b*y; x=temp; 22 } 23 int main() 24 { 25 LL a,b,c,x1,x2,y1,y2; 26 LL x,y; 27 LL tx1,tx2,ty1,ty2; 28 cin>>a>>b>>c>>x1>>x2>>y1>>y2; 29 LL r=gcd(a,b),r1,r2; 30 if (a==0&&b==0) 31 { 32 if (c==0) cout<<(x2-x1+1)*(y2-y1+1)<<endl; 33 else cout<<0<<endl; 34 } 35 else if (a==0||b==0) 36 { 37 if (a==0) swap(a,b),swap(x1,y1),swap(x2,y2); 38 if (c%a!=0) cout<<0<<endl; 39 else if (-c/a>=x1&&-c/a<=x2) cout<<(y2-y1+1)<<endl; 40 else cout<<0<<endl; 41 } 42 else if (c%r!=0) printf("0\n"); 43 else 44 { 45 _gcd(a/r,b/r,x,y); 46 x*=-c/r; y*=-c/r; 47 r=a*b/r; r1=r/a; r2=r/b; 48 tx1=x1-x; tx2=x2-x; if (r1<0) swap(tx1,tx2),tx1=-tx1,tx2=-tx2,r1=-r1; 49 ty1=-y2+y; ty2=-y1+y; if (r2<0) swap(ty1,ty2),ty1=-ty1,ty2=-ty2,r2=-r2; 50 tx1=ceil(double(tx1)/r1); tx2=floor(double(tx2)/r1); 51 ty1=ceil(double(ty1)/r2); ty2=floor(double(ty2)/r2); 52 tx1=max(tx1,ty1); tx2=min(tx2,ty2); 53 if (tx2>=tx1) cout<<tx2-tx1+1<<endl; 54 else cout<<0<<endl; 55 } 56 return 0; 57 }
标签:style blog http color os io ar art div
原文地址:http://www.cnblogs.com/monmonde/p/3933338.html