一本通1638五指山

1638:五指山

时间限制: 1000 ms         内存限制: 524288 KB

【题目描述】

原题来自:NEFU 84

大圣在佛祖的手掌中。

我们假设佛祖的手掌是一个圆圈,圆圈的长为 n,逆时针记为:0,1,2,,n1,而大圣每次飞的距离为 d。现在大圣所在的位置记为 x,而大圣想去的地方在 y。要你告诉大圣至少要飞多少次才能到达目的地。

【输入】

有多组测试数据。

第一行是一个正整数 T,表示测试数据的组数;

每组测试数据包括一行,四个非负整数,分别为如来手掌圆圈的长度 n,筋斗所能飞的距离 d,大圣的初始位置 x 和大圣想去的地方 y

注意孙悟空的筋斗云只沿着逆时针方向翻。

【输出】

对于每组测试数据,输出一行,给出大圣最少要翻多少个筋斗云才能到达目的地。如果无论翻多少个筋斗云也不能到达,输出 Impossible

【输入样例】

2
3 2 0 2
3 2 0 1

【输出样例】

1
2

【提示】

数据范围与提示:

对于全部数据,2<n<109,0<d<n,0x,y<n

 

sol:非常模板的一道题目

S+d*k = T (%Mod)
d*k+Mod*k' = T-S (类ax+by=c的形式)

/*
    S+d*k = T (%Mod)
    d*k+Mod*k' = T-S (类ax+by=c的形式)
*/
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
inline ll read()
{
    ll s=0;
    bool f=0;
    char ch=' ';
    while(!isdigit(ch))
    {
        f|=(ch=='-'); ch=getchar();
    }
    while(isdigit(ch))
    {
        s=(s<<3)+(s<<1)+(ch^48); ch=getchar();
    }
    return (f)?(-s):(s);
}
#define R(x) x=read()
inline void write(ll x)
{
    if(x<0)
    {
        putchar('-'); x=-x;
    }
    if(x<10)
    {
        putchar(x+'0');    return;
    }
    write(x/10);
    putchar((x%10)+'0');
    return;
}
#define W(x) write(x),putchar(' ')
#define Wl(x) write(x),putchar('\n')
int Q;
ll Mod,d,S,T;
inline ll gcd(ll x,ll y)
{
    return (!y)?(x):(gcd(y,x%y));
}
inline void Exgcd(ll a,ll b,ll &X,ll &Y)
{
    if(b==0)
    {
        X=1;
        Y=0;
        return;
    }
    Exgcd(b,a%b,X,Y);
    ll XX=X,YY=Y;
    X=YY;
    Y=XX-a/b*YY;
    return;
}
int main()
{
    R(Q);
    while(Q--)
    {
        R(Mod); R(d); R(S); R(T);
        ll a=d,b=Mod,c=T-S;
        ll r=gcd(a,b),X,Y;
        if(c%r)
        {
            puts("Impossible");
            continue;
        }
        Exgcd(a,b,X=0,Y=0);
        X=X*c/r;
        ll tmp=b/r;
        X=(X%tmp+tmp)%tmp;
        Wl(X);
    }
    return 0;
}
View Code

 

posted @ 2019-03-05 22:15  yccdu  阅读(396)  评论(0编辑  收藏  举报