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' ,就会出现一个整点。
所以这道题目的关键就是,我们先求出一组解,然后通过它的 b' 将x0改变成x,使得x在[x1,x2]区间之内,这样每 b' 个单位就有一个整点了,即
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<vector>
#include<stack>
#include<queue>
#include<cmath>
#include<map>
using namespace std; typedef long long LL;
double X1,Y1,X2,Y2; void gcd(LL a,LL b,LL& d,LL& x,LL& y)
{
if(!b) {d=a;x=;y=;}
else { gcd(b,a%b,d,y,x); y-=x*(a/b);}
} LL solve()
{
LL x1=X1*, y1=Y1*, x2=X2*, y2=Y2*;
if(x1==x2) //平行y轴
{
if(x1%) return ; //原来的X1为小数,肯定不是整点
if(Y2<Y1) swap(Y1,Y2);
return floor(Y2)-ceil(Y1)+;
}
if(y1==y2)
{
if(y1%) return ;
if(X2<X1) swap(X1,X2);
return floor(X2)-ceil(X1)+;
}
LL a=(y2-y1)*, b=(x1-x2)*, c=y2*x1-y1*x2; //c相当于扩大了100倍,所以前面还得乘10
LL d,x,y;
gcd(a,b,d,x,y);
if(c%d) return ; //扩展欧几里得算法无解的判断 x=x*c/d; y=y*c/d; //获得一组整数解(x,y)
b=abs(b/d); //这里的b其实就是b' if(X1>X2) swap(X1,X2);
x1=ceil(X1);
x2=floor(X2);
if(x1>x2) return ; x=x+(x1-x)/b*b; //使x进入[x1,x2]的区间内
if(x<x1) x+=b;
if(x>x2) return ;
return (x2-x)/b+;
} int main()
{
//freopen("D:\\input.txt","r",stdin);
int T;
scanf("%d",&T);
while(T--)
{
scanf("%lf%lf%lf%lf",&X1,&Y1,&X2,&Y2);
LL ans = solve();
printf("%lld\n",ans);
}
return ;
}
UVa 11768 格点判定(扩展欧几里得求线段整点)的更多相关文章
- UVA 12169 Disgruntled Judge 枚举+扩展欧几里得
题目大意:有3个整数 x[1], a, b 满足递推式x[i]=(a*x[i-1]+b)mod 10001.由这个递推式计算出了长度为2T的数列,现在要求输入x[1],x[3],......x[2T- ...
- hdu_1576A/B(扩展欧几里得求逆元)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1576 A/B Time Limit: 1000/1000 MS (Java/Others) Me ...
- 扩展欧几里得 求ax+by == n的非负整数解个数
求解形如ax+by == n (a,b已知)的方程的非负整数解个数时,需要用到扩展欧几里得定理,先求出最小的x的值,然后通过处理剩下的区间长度即可得到答案. 放出模板: ll gcd(ll a, ll ...
- POJ - 1061 青蛙的约会 (扩展欧几里得求同余式)
题意:两只青蛙在网上相识了,它们聊得很开心,于是觉得很有必要见一面.它们很高兴地发现它们住在同一条纬度线上,于是它们约定各自朝西跳,直到碰面为止.可是它们出发之前忘记了一件很重要的事情,既没有问清楚对 ...
- C Looooops(扩展欧几里得求模线性方程)
http://poj.org/problem?id=2115 题意:对于C的循环(for i = A; i != B; i+=C)问在k位存储系统内循环多少次结束: 若循环有限次能结束输出次数,否则输 ...
- 51Nod 1256 扩展欧几里得求乘法逆元
给出2个数M和N(M < N),且M与N互质,找出一个数K满足0 < K < N且K * M % N = 1,如果有多个满足条件的,输出最小的. Input 输入2个数M, N中间用 ...
- poj 2891 扩展欧几里得迭代解同余方程组
Reference: http://www.cnblogs.com/ka200812/archive/2011/09/02/2164404.html 之前说过中国剩余定理传统解法的条件是m[i]两两互 ...
- poj 2142 扩展欧几里得解ax+by=c
原题实际上就是求方程a*x+b*y=d的一个特解,要求这个特解满足|x|+|y|最小 套模式+一点YY就行了 总结一下这类问题的解法: 对于方程ax+by=c 设tm=gcd(a,b) 先用扩展欧几里 ...
- J - 青蛙的约会(扩展欧几里得)
https://vjudge.net/contest/218366#problem/J 第一步追及公式要写对:y+nk-(x+mk)=pL => (n-m)k+lp=x-y 可以看出扩展欧几里得 ...
随机推荐
- 原型模式(Prototype Pattern)--对象的克隆
定义:使用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象; 原型类的核心在于如何实现克隆方法: 能够实现克隆的Java类必须实现一个标识接口Cloneable,表示这个类支持被复制; 通 ...
- LINUX内核分析20133201
实验:通过汇编一个简单的C程序,分析汇编代码理解计算机是如何工作的 学号:20133201 姓名:李冬辉 注: 原创作品转载请注明出处 +<Linux内核分析>MOOC课程http://m ...
- 对Numpy数组按axis运算的理解
Python的Numpy数组运算中,有时会出现按axis进行运算的情况,如 >>> x = np.array([[1, 1], [2, 2]]) >>> x arr ...
- java中的静态分派和动态分派
多态是java的基本特征之一,多态即一个对象具有多种形态(多种表达形式,猴子是动物的一种的表现形式),例如:子类是父类的一种形态. 当方法重载时,就会涉及到多态. 1:在重载时是通过参数的静态类型,而 ...
- 微信js-sdk使用
<?php $appid=""; $secret=""; class JSSDK { private $appId; private $appSecret ...
- Linux kill和kill-9区别
进程状态转换图 kill和kill -9,两个命令在linux中都有杀死进程的效果,然而两命令的执行过程却大有不同,在程序中如果用错了,可能会造成莫名其妙的现象. 执行kill命令,系统会发送一个SI ...
- strtok - 详细示例解析
定义: Defined in header <string.h> 原型: char strtok( char str, const char *delim ); 参数: 2个都是字符串(以 ...
- python 中元祖tuple的使用
Python的元组与列表类似,不同之处在于元组的元素不能修改. 元组使用小括号,列表使用方括号. 元组创建很简单,只需要在括号中添加元素,并使用逗号隔开即可. eg, tup1 = (1, 2, 3 ...
- 浅析selenium的PageFactory模式 PageFactory初始化pageobject
1.首先介绍FindBy类: For example, these two annotations point to the same element: @FindBy(id = "foob ...
- HTTPS复习
Https Https其实是两个协议,即HTTP协议和SSL协议,但是由于HTTP协议应用广泛,而且需要为其提供数据隐私保护,所以将HTTP协议与SSL协议结合.HTTP属于应用层,在远古时代,它只需 ...