一本通1638五指山
1638:五指山
时间限制: 1000 ms 内存限制: 524288 KB【题目描述】
原题来自:NEFU 84
大圣在佛祖的手掌中。
我们假设佛祖的手掌是一个圆圈,圆圈的长为 n,逆时针记为:0,1,2,⋯,n−1,而大圣每次飞的距离为 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,0≤x,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; }
河田は河田、赤木は赤木……。
私は誰ですか。教えてください、私は誰ですか。
そうだ、俺はあきらめない男、三井寿だ!