HDU4596 Yet another end of the world 扩展欧几里德性质

这题坑了,我真该吃翔啊,居然一开始方程设错了而且没有去想连列的问题,我真是坑货,做不出就该重新理一下嘛,操蛋,

题意:给了N组x,y,z然后 问你是否存在两个或者两个以上的id,是的 id%x的值在区间[y,z]之间,若有则输出Cannot Take off

否则你懂得

根据题意 那么  列出 :

a*x1  + y1 <= id <= a*x1 + z1

b * x2 + y2 <= id <= b*x2 + z2,

假设有解的话,那么这两个区间肯定有重复部分,,那么继续推得:

a*x1 <= b*x2 + z2 和 b *x2 + y2 <= a*x1 + z1

化简可以得到

a* x1 - b* x2 <= z2 - y1  1号式子

b * x2 - a*x1 <= z1 - y2   2号式子

为了统一 再把2号变成

a*x1 - b*x2 <= y2 - z1

然后看到这个应该就要想到扩展欧几里德,若存在非负的且不都为0整数a,b,必然存在整数对 x,y使得  gcd(a,b) = a*x + b*y,

应用到这道题目上也就是  要求  gcd(x1,x2) = a*x1 + (- b*x2)  这个式子存在解,这个式子的值同时又是  z2 - y1所以实际上就是转化成了

gcd(x1,x2)与 z2 - y1得有整数倍的关系 ,意思就是  (z2-y1)%gcd(x1,x2) == 0,注意是取模,竟然看到有篇题解写的是除号,做完想看看别人做法时看到这里坑了我一下,还以为我推的有问题呢,原来是他自己写错了,问题是居然另外有人的题解 直接复制了 他的解析,唉~~~~~

同时对于式子2我们也可以推到  (y2 - z1)%)gcd(x1,x2) == 0  这两个其中任意一个满足即可,区间覆盖部分 不用严格包含,语文不太好说不清楚,反正留给自己长脑子的

题目给出了N组,N的范围为1000,直接扫两层暴力来判断就可以了,

我的判断是否整除部分是:

int cal(int a,int b,int c) {
	if(c%a == 0 || b%a == 0)return 1;//不等式相等情况时的整除
	return 0;
}

其他人的题解判断部分是:

bool isok(int t,int le,int ri)
{
    int i,j;
    if(le%t==0||ri%t==0) return true ;
    if(le<0&&ri>=0) return true ;
    if(ri/t-le/t>0) return true ;
    return false ;
}  

而且目前为止我看到的网上的题解的 所有人的判断部分 如出一辙啊,全都是如上述所示的那样,但是我少了下面那两个if判断过了,是题目数据太水了吗,下面两个判断我还这么没搞懂,是我这个弱菜漏了什么吗,路过有大神请教指点啊,

#include<iostream>
#include<cstdio>
#include<list>
#include<algorithm>
#include<cstring>
#include<string>
#include<queue>
#include<stack>
#include<map>
#include<vector>
#include<cmath>
#include<memory.h>
#include<set>

#define ll long long

#define eps 1e-8

#define inf 0xfffffff

const ll INF = 1ll<<61;

using namespace std;

//vector<pair<int,int> > G;
//typedef pair<int,int > P;
//vector<pair<int,int> > ::iterator iter;
//
//map<ll,int >mp;
//map<ll,int >::iterator p;

const int N = 1000 + 5;

int x[N],y[N],z[N];

void init() {
	memset(x,0,sizeof(x));
	memset(y,0,sizeof(y));
	memset(z,0,sizeof(z));
}

int gcd(int a,int b) {
	return b==0?a:gcd(b,a%b);
}

int cal(int a,int b,int c) {
	if(c%a == 0 || b%a == 0)return 1;//不等式相等情况时的整除
	return 0;
}

int main() {
	int n;
	while(scanf("%d",&n) == 1) {
		init();
		for(int i=0;i<n;i++)
			scanf("%d %d %d",&x[i],&y[i],&z[i]);
		bool flag = false;
		for(int i=0;i<n;i++) {
			for(int j=i + 1;j<n;j++) {
				int tmp = gcd(x[i],x[j]);
				if(cal(tmp,z[j] - y[i],y[j] - z[i])) {
					flag = true;
				}
			}
		}
		if(flag)
			puts("Cannot Take off");
		else
			puts("Can Take off");
	}
	return 0;
}

HDU4596 Yet another end of the world 扩展欧几里德性质

时间: 2024-08-24 16:27:28

HDU4596 Yet another end of the world 扩展欧几里德性质的相关文章

扩展欧几里德算法

文章来源:http://blog.csdn.net/zhjchengfeng5/article/details/7786595 谁是欧几里德?自己百度去 先介绍什么叫做欧几里德算法 有两个数 a b,现在,我们要求 a b 的最大公约数,怎么求?枚举他们的因子?不现实,当 a b 很大的时候,枚举显得那么的na?ve ,那怎么做? 欧几里德有个十分又用的定理: gcd(a, b) = gcd(b , a%b) ,这样,我们就可以在几乎是 log 的时间复杂度里求解出来 a 和 b 的最大公约数了

POJ2142 The Balance (扩展欧几里德)

本文为博主原创文章,欢迎转载,请注明出处 www.cnblogs.com/yangyaojia The Balance 题目大意  你有一个天平(天平左右两边都可以放砝码)与重量为a,b(1<=a,b<=10000)的两种砝码.让你求出一种方案称出重为c(1<=c<=50000)的物品,如有多种方案,请输出两种砝码需要数量的总和最小的方案. 输入 有若干行,每行三个数,a,b,c. 结束时用0 0 0表示. 输出 若干行,每行两个数,表示每个询问中a的数量与b的数量 如果无解输出 

欧几里德与扩展欧几里德算法(转)

欧几里德算法 欧几里德算法又称辗转相除法,用于计算两个整数a,b的最大公约数. 基本算法:设a=qb+r,其中a,b,q,r都是整数,则gcd(a,b)=gcd(b,r),即gcd(a,b)=gcd(b,a%b). 第一种证明: a可以表示成a = kb + r,则r = a mod b 假设d是a,b的一个公约数,则有 d|a, d|b,而r = a - kb,因此d|r 因此d是(b,a mod b)的公约数 假设d 是(b,a mod b)的公约数,则 d | b , d |r ,但是a

欧几理德,扩展欧几里德和模线性方程组。

欧几里德算法: 即求两个整数的最大公约数的一种快捷算法.也就是通常所说的“辗转相除法”.给定两个整数 a, b.欧几里德最坏可以在log(max(|a|, |b|))的复杂度内求出a, b的最大公约数.时间复杂度的计算方法也很有意思, 详见<算法导论>. 证明欧几里德算法的正确性: a可以表示成a = kb + r,且 r = a mod b 我们要证明欧几里德算法的正确性 也即是证明 gcd(a, b) = gcd(b, a%b=r) 假设d是a,b的一个公约数,则有 d|a, d|b,而r

HDU 1098 Ignatius&#39;s puzzle 费马小定理+扩展欧几里德算法

题目大意: 给定k,找到一个满足的a使任意的x都满足 f(x)=5*x^13+13*x^5+k*a*x 被65整除 推证: f(x) = (5*x^12 + 13 * x^4 + ak) * x 因为x可以任意取 那么不能总是满足 65|x 那么必须是 65 | (5*x^12 + 13 * x^4 + ak) 那么就是说 x^12 / 13 + x^4 / 5 + ak / 65 正好是一个整数 假设能找到满足的a , 那么将 ak / 65 分进x^12 / 13 + x^4 / 5中得到

POJ 2891-Strange Way to Express Integers(扩展欧几里德)

题目地址:POJ 2891 题意:给你k组同余关系,每组包含一个ai和ri,让你找出一个最小的数m,满足m%a1=r1,m%a2=r2.......m%ak=rk. 思路:纵观上述公式,很熟悉,其实就是求两两公式之间的最小值,例如K=3,那么先求第一组和第二组的最小,然后合并第一组和第二组,然后用合并之后的再和第三组找最小,最后的结果就是最终的结果.也就是这个题分两部分来完成. 1.找出两组最小.对于m%a1=r1和m%a2=r2可以得出两个公式m=a1*x+r1,m=a2*y+r2(x,y相当

HDU 2669 Romantic(扩展欧几里德)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2669 Problem Description The Sky is Sprite. The Birds is Fly in the Sky. The Wind is Wonderful. Blew Throw the Trees Trees are Shaking, Leaves are Falling. Lovers Walk passing, and so are You. ..........

POJ1061——青蛙的约会(扩展欧几里德)

青蛙的约会 Description两只青蛙在网上相识了,它们聊得很开心,于是觉得很有必要见一面.它们很高兴地发现它们住在同一条纬度线上,于是它们约定各自朝西跳,直到碰面为止.可是它们出发之前忘记了一件很重要的事情,既没有问清楚对方的特征,也没有约定见面的具体位置.不过青蛙们都是很乐观的,它们觉得只要一直朝着某个方向跳下去,总能碰到对方的.但是除非这两只青蛙在同一时间跳到同一点上,不然是永远都不可能碰面的.为了帮助这两只乐观的青蛙,你被要求写一个程序来判断这两只青蛙是否能够碰面,会在什么时候碰面.

HihoCoder - 1297 数论四&#183;扩展欧几里德

描述 小Hi和小Ho周末在公园溜达.公园有一堆围成环形的石板,小Hi和小Ho分别站在不同的石板上.已知石板总共有m块,编号为 0..m-1,小Hi一开始站在s1号石板上,小Ho一开始站在s2号石板上. 小Hi:小Ho,你说我们俩如果从现在开始按照固定的间隔数同时同向移动,我们会不会在某个时间点站在同一块石板上呢? 小Ho:我觉得可能吧,你每次移动v1块,我移动v2块,我们看能不能遇上好了. 小Hi:好啊,那我们试试呗. 一个小时过去了,然而小Hi和小Ho还是没有一次站在同一块石板上. 小Ho:不