题目分析
这道题考虑了很久,但还是有点东西没有想明白,细节的处理方面,我感觉都能想到,就是最后一步求有多少个点在给定范围中,实在不知道巨巨们是怎么搞出来的,有知道的大神可以告诉我那个是怎么搞得可以给我发私信,在这里谢谢了。数学功底太差,需要恶补一下。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
typedef long long LL;
void exgcd(LL a,LL b,LL &d,LL &x,LL &y)
{
if(!b) {x = 1; y = 0; d = a;}
else{
exgcd(b, a%b, d, y, x);
y -= x*(a/b);
}
}
int main()
{
LL a,b,c,x1,x2,y1,y2;
while(scanf("%I64d%I64d%I64d%I64d%I64d%I64d%I64d", &a, &b, &c, &x1, &x2, &y1, &y2) != EOF)
{
c = -c;
LL d,x,y,t;
if(x1 > x2 || y1 > y2){ //特判
printf("0\n");
continue;
}
if(a == 0 && b == 0){
if(c == 0) printf("%I64d\n", (x2-x1+1)*(y2-y1+1));
else printf("0\n");
}
else if(a == 0 && b != 0)
{
if(c%b == 0 && c/b >= y1 && c/b <= y2)
printf("%I64d\n", x2-x1+1);
else printf("0\n");
}
else if(a != 0 && b == 0)
{
if(c%a == 0 && c/a >= x1 && c/a <= x2)
printf("%I64d\n", y2-y1+1);
else printf("0\n");
}
else{
if(a < 0){ //将a和b都处理为正数
t = x1; x1 = -x2; x2 = -t; a = -a;
}
if(b < 0){
t = y1; y1 = -y2; y2 = -t; b = -b;
}
exgcd(a, b, d, x, y);
if(c%d) printf("0\n"); //不存在整数解
else{ //找出满足x1 <= (x + b/d * k) <= x2 && y1 <= (y - a/d * k) <= y2的k的个数
x *= c/d;
y *= c/d;
LL m1 = b/d, m2 = a/d;
double L1 = (x1-x)*1.0/m1,L2 = (x2-x)*1.0/m1;
if(L1 > L2) swap(L1,L2);
LL ld1 = ceil(L1), ld2 = floor(L2);
double R1 = (y-y1)*1.0/m2, R2 = (y-y2)*1.0/m2;
if(R1 > R2) swap(R1, R2);
LL rd1 = ceil(R1), rd2 = floor(R2);
LL L = max(ld1,rd1);
LL R = min(ld2,rd2);
if(L > R) printf("0\n");
else printf("%I64d\n", R-L+1);
}
}
}
return 0;
}