HDU 4596 J - Yet another end of the world(数论)

题意:

给你n个 xi yi zi ,让你判断是否存在一个数num, 满足形如下式的条件,满足的话则代表此飞船在这个虫洞的作用力下,那么这个num号飞船不能再同时再处于另一个冲动的引力下,否则会被潮汐力撕碎。。。现在问你是否有被撕碎的危险。

y<=num(modxi)<=z

思路:

遍历两两组合的全部。对于任意的两个有如下的特点。

nummodx1=r1(1)

nummodx2=r2(2)

即:
num=k1x1+r1=k2x2+r2

经过化简:
k1x1k2x2=r2r1(3)

(3)式是典型的二元一次不定方程,有解的充要条件是 gcd(k1,k2)|(r2r1) 即:( r2 - r1 ) % gcd( k1 , k2 ) = 0

对于这两个区间来说,如果相交,那么必可选出相等的点使得 r2 - r1 =0,从而有解。但不相交的情况也有可能有解,我们假设在左边的那个区间为y1,z1,右边的为y2,z2,这时 r2 - r1 的取值范围就在 [y2z1,z2y1] 间了,我们这时只需判断这个区间里是否有模g = gcd( k1 , k2 )等于0的数就好了。

判断的方法:如果 y2z1 % g 不为零并且 z2y1 并没有超过g的循环节。具体代码如下:

代码:

#include <iostream>
#include <cstdio>
#include <string.h>

typedef long long int lli;

using namespace std;
lli flag = 0;
lli gcd(lli a,lli b){
    return b == 0 ? a:gcd(b,a%b);
}
struct node{
    lli x,y,z;
}a[1050];
bool f(int ii,int jj){
    if( (a[ii].z >= a[jj].y && a[ii].y < a[jj].z)
        || (a[jj].z >= a[ii].y && a[jj].y < a[ii].z)){
        return true;
    }
    if(a[ii].y > a[jj].z){
        swap(ii,jj);
    }
    lli from = a[jj].y-a[ii].z;
    lli to = a[jj].z-a[ii].y;
    lli gc = gcd(a[ii].x,a[jj].x);
    if(from % gc != 0 && to-from <= gc-from%gc-1){
        return false;
    }
    return true;;
}
int main(){
    int n;
    while(~scanf("%d",&n)){
        flag = 0;
        for(int i = 1;i <= n;i++){
            scanf("%lld%lld%lld",&a[i].x,&a[i].y,&a[i].z);
        }
        for(int i = 1; i< n;i++){
            for(int j = i+1;j <= n;j++){
                if(f(i,j)){
                    flag = 1;
                    break;
                }
            }
            if(flag == 1) break;
        }
        if(flag == 0){
            puts("Can Take off");
        }
        else
            puts("Cannot Take off");
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值