当前位置: 代码迷 >> 综合 >> UVa 11768 Lattice Point or Not
  详细解决方案

UVa 11768 Lattice Point or Not

热度:75   发布时间:2023-12-15 07:47:11.0

题目

https://vjudge.net/problem/UVA-11768

题解

上一次做到这里感觉很烦躁写不出来跳到数据结构去了,然后隔了两天重新回来做,做了一下午加半个晚上,vjudge提交记录一版都是我的qwq。

首先思路一定要清晰,这题变量多得不得了,调试非常困难,经常调到一半,诶我要求啥来着?这是啥意思?这个等于啥?

思路:先找到这条线段上的一个整点(没有就特判),然后计算出每隔多长会出现一个整点,利用这两个信息找出线段上最接近x较小的那个点的整点,然后计算一下这里到x较大那个点会出现多少整点。

大体框架是这样,然后一步一步实现。

先找整点,这题很讨厌的就是坐标是0.1的整数倍(还好不是0.01的整数倍),所以考虑把坐标全部扩大10倍,因为根据两点式推出直线方程是 (y2?y1)x+(x1?x2)y=x2y1?y1x2 ,设 a=y2?y1,b=x1?x2,c=x2y1?y1x2 ,那么此时a和b为0.1的倍数,c为0.01的倍数,我们现在没有办法直接找出一组解来,因为并不是整数。所以两边同乘100,这样就能找出一组解。

还可以表示出通解,x的通解可表示为 x=x0+k?b,b=b/gcd(a,b) 其实这个b’就是每隔多长会出现一个整点了。然后照上面说的算一下就好了。

另外注意特判两个点横坐标或者纵坐标相等的情况,这种情况很好算的。注意算的时候c可能会爆int,要开longlong。

qwq理解起来有一定难度。

代码

//QWsin
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;void exgcd(long long  a,long long  b,long long  &g,long long  &x,long long  &y)
{if(!b){g=a;x=1;y=0;return ;}exgcd(b,a%b,g,y,x);y-=a/b*x;
}inline long long  solve()
{double X1,Y1,X2,Y2;cin>>X1>>Y1>>X2>>Y2;long long  x1=X1*10,y1=Y1*10,x2=X2*10,y2=Y2*10;if(x1==x2){if(x1%10) return 0;if(Y1>Y2) swap(Y1,Y2);return max((long long )(floor(Y2)-ceil(Y1)+1),0ll);}if(y1==y2){if(y1%10) return 0;if(X1>X2) swap(X1,X2);return max((long long )(floor(X2)-ceil(X1)+1),0ll);}long long  a=(y2-y1)*10,b=(x1-x2)*10,g,x,y,c=y2*x1-x2*y1;exgcd(a,b,g,x,y);if(c%g!=0) return 0;a/=g;b/=g;x*=c/g;y*=c/g;if(b<0) b=-b;if(X1>X2) swap(X1,X2);x1=ceil(X1),x2=floor(X2);if(x1>x2) return 0;x=x-(x-x1)/b*b;if(x<x1) x+=b;if(x>x2) return 0;return (x2-x)/b+1;
}int  main()
{long long  T;cin>>T;while(T--) printf("%lld\n",solve());return 0;
}
  相关解决方案