D. The Beatles

时间:2024-01-03 16:59:08

链接

[https://codeforces.com/contest/1143/problem/D]

题意

就是有nkcity,n个面包店

第一个面包店在1city,第x个在(x-1)
k+1city

已知刚开始起步离最近面包店的距离和跳第一次之后离面包店最近的距离

问你最多需要走调少次回到出发地和最少的跳次数

分析

我是看官方题解才知道这么回事收获不小

就是一定去用已知条件去确定某些情况

缩小需要枚举的范围,分析能力还是不够强啊

首先我们不知道每次要跳多远

但是你的出发点是可以确定,一旦出发点确定,那么跳多少也可确定但情况很多

暴力枚举是会tle的,我们假设跳的是l

那么跳回到出发地的次数是n⋅k/gcd(n⋅k,l)

那么设l=k*x+c; x,c未知,但一定是非负的。因为不可能反方向跳

但有a,b;

c是可以确定的((a+b)%k,(a−b)%k,(b−a)%k,(−a−b)%k),

只有四种情况,自己画图模拟不同出发地和不同第一次跳的地点就知道了

然后这个k的范围就是0到n-1因为最多有n个面包店

代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll n,k,a,b;
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
while(cin>>n>>k>>a>>b){
ll f[4];
f[1]=a+b,f[0]=a-b,f[2]=b-a,f[3]=-a-b;
ll x=1e18,y=-1;
for(int i=0;i<n;i++){
for(int j=0;j<4;j++){
ll c=(f[j]+k)%k;
ll l=k*i+c;
x=min(x,n*k/__gcd(n*k,l));
y=max(y,n*k/__gcd(n*k,l));
}
}
cout<<x<<' '<<y<<endl;
}
return 0;
}