UVA 11768 Lattice Point or Not

扩展欧几里得,给两个点,就可以求出直线方程为 (yy-y)*x0 + (x-xx)*y0 = x*yy - y*xx,求的是在线段上的整点个数。所以就是(yy-y)*10*x0 + (x-xx)*10*y0 = x*yy - y*xx满足条件的解的个数。用exgcd搞之后求出一个解,再求出在线段上第一个整点的位置,然后再求有多少个在线段上的点。

exgcd有点忘了,还有就是特殊情况的判断(比如平行坐标轴),另外就是不能交换输入点,输入

1.0 0.3 0.3 10.0交换后就是0.3 0.3 1.0 10.0就变成有整点了,下次一定要注意,多想想

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cstdio>
 5 #include<cmath>
 6 #include<string>
 7 #include<algorithm>
 8
 9 using namespace std;
10 #define inf 0x3f3f3f3f
11 #define eps 1e-8
12 #define LL long long
13 #define ull unsigned long long
14 #define mnx 1005
15
16 void exgcd( LL a, LL b, LL &d, LL &x, LL &y ){
17     if( !b ) {
18         d = a, x = 1, y = 0;        // d恰好是最大公约数
19     }
20     else {
21         exgcd( b, a%b, d, y, x );
22         y -= x*(a/b);
23     }
24 }
25 double ax, ay, bx, by;
26 void solve(){
27     if( ax > bx ) swap( ax, bx );
28     if( ay > by ) swap( ay, by );
29     LL x = ax * 10, y = ay * 10, xx = bx * 10, yy = by * 10;
30     if( x == xx || y == yy ){
31         if( x == xx ) swap( ax, ay ), swap( bx, by ), swap( x, y ), swap( xx, yy );
32         if( yy % 10 ){
33             puts( "0" ); return ;
34         }
35         x = ceil( ax ) * 10, xx = floor( bx ) * 10;
36         cout << x << " " << xx << endl;
37         if( xx < x ){
38             puts( "0" ); return ;
39         }
40         printf( "%lld\n", (xx-x)/10 + 1LL ); return ;
41     }
42     LL a = ( yy - y ) * 10, b = ( x - xx ) * 10, c = x * yy - y * xx, d, x0, y0;
43     //cout << a << " "<< b <<endl;
44     exgcd( a, b, d, x0, y0 );
45     //cout <<c <<" " << d << endl;
46     if( c % d ){
47         puts( "0" ); return ;
48     }
49     x = ceil( ax ), xx = floor( bx );
50     y = ceil( ay ), yy = floor( by );
51     //cout << 1 << endl;
52     if( x > xx || y > yy ){
53         puts( "0" ); return ;
54     }
55     x0 = x0 * ( c / d );
56     //cout << x0 << endl;
57     b /= d;
58     if( b < 0 ) b = -b;
59     x0 = x0 - ( x0 - x ) / b * b;
60     x0 -= b;
61     while( x0 < x ) x0 += b;
62     LL ans = ( xx - x0 ) / b;
63     while( x0 + ans * b <= xx ) ans++;
64     printf( "%lld\n", ans );
65 }
66 int main(){
67     int cas;
68     scanf( "%d", &cas );
69     while( cas-- ){
70         scanf( "%lf%lf%lf%lf", &ax, &ay, &bx, &by );
71         solve();
72     }
73     return 0;
74 }

时间: 2024-10-12 15:36:21

UVA 11768 Lattice Point or Not的相关文章

UVA 11768 - Lattice Point or Not(数论)

UVA 11768 - Lattice Point or Not option=com_onlinejudge&Itemid=8&page=show_problem&category=516&problem=2868&mosmsg=Submission+received+with+ID+13823461" target="_blank" style="">题目链接 题意:给定两个点,构成一条线段.这些点都是十分

UVA - 11768 Lattice Point or Not (拓展gcd)

Now a days a very common problem is:"The coordinate of two points in Cartesian coordinate system is (200, 300) and(4000, 5000). If these two points are connected we get a line segment. How manylattice points are there on this line segment." You

UVA - 11768 Lattice Point or Not (扩展欧几里得)

求一条线段上有多少个整点. 是道扩欧基础题,列出两点式方程,然后分四种情况讨论即可.但细节处理较多很容易写挫(某zzWA了十几发才过掉的). 由于数据精度较小,浮点数比较没有用eps,直接==比较了. 1 #include<bits/stdc++.h> 2 3 using namespace std; 4 typedef long long ll; 5 6 void exgcd(ll a,ll b,ll& x,ll& y,ll& g) { 7 if(!b)x=1,y=0

uva 1549 - Lattice Point(暴力)

题目链接:uva 1549 - Lattice Point 题目大意:给定圆半径,以原点为圆心,求园内有多少个整数点. 解题思路:首先坐标轴将圆分成4份,所以只要单独考虑每一块的个数乘4再加1即可(原点) #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; const double pi = 4 * atan(1.0);

UVA - 1602 Lattice Animals (暴力+同构判定)

题目链接 题意:求能放进w*h的网格中的不同的n连通块个数(通过平移/旋转/翻转后相同的算同一种),1<=n<=10,1<=w,h<=n. 刘汝佳的题真是一道比一道让人自闭...QAQ~~ 这道题没什么好的办法,Polya定理也毫无用武之地,只能暴力构造出所有可能的连通块,然后用set判重,比较考验基本功. 连通块可以用一个结构体D来表示,D的n代表黑块数量,然后有至多10个点P(x,y),用另一个结构体数组P[N]来表示. 问题的关键在于如何判重. 首先要知道set是通过<

UVa 11768 格点判定(扩展欧几里得求线段整点)

https://vjudge.net/problem/UVA-11768 题意: 给定两个点A(x1,y1)和B(x2,y2),均为0.1的整数倍.统计选段AB穿过多少个整点. 思路: 做了这道题之后对于扩展欧几里得有了全面的了解. 根据两点式公式求出直线 ,那么ax+by=c 中的a.b.c都可以确定下来了. 接下来首先去计算出一组解(x0,y0),因为根据这一组解,你可以写出它的任意解,其中,K取任何整数. 需要注意的是,这个 a' 和 b' 是很重要的,比如说 b' ,它代表的是x每隔 b

UVA 1602 Lattice Animals解题思路(打表+set)

题目链接 https://vjudge.net/problem/UVA-1602 紫书的一道例题,跟之前的很多题目有很多不同. 本题不像是一般的dfs或bfs这样的搜索套路,而是另一种枚举思路. 题意: 输入n. w. h(1≤n≤10,1≤w,h≤n),求能放在w*h网格里的不同的n连块的个数(平移. 旋转. 翻转后相同的图形算作同一种). 思路: 思路很明确,生成图形后判重,加入重复表或弃掉. 本题的重点就在生成和判重. 我的思路: 连通块的生成:通过维护一个int open[10][10]

数论小结1.

从白书上面的习题开始版切....但是发现时间不够了.... 今天粗略的做了不少题目.....但是有些题目感觉实在是比较诡异.......感觉考的话也不太可能...不过还是写下来吧. 1.Uva 10673 已知x, k, 求 x = p * floor(x / k) + q * ceil(x / k).的解. 思路: 其实分类讨论就 ok 了. 当 x % k == 0 时, 取 p = x * k, q = 0; 否则, floor 与 ceil 相差 1. 怎么做? 你懂得. 2. Uva

UVA - 12075 Counting Triangles

Description Triangles are polygons with three sides and strictly positive area. Lattice triangles are the triangles all whose vertexes have integer coordinates. In this problem you have to find the number of lattice triangles in anMxN grid. For examp