CF #549 D. The Beatles
题意:由1到N个节点组成一个环,从节点1开始,每隔k个节点有一个餐馆(1也有餐馆)
现给出4个数据n,k,a,b
n为餐馆的数量,k为餐馆之间的间隔距离,a为起始位置距离最近餐馆的距离,b为走了一步(步数未知)后距离最近餐馆的距离
思路:这题的未知数是每步所走路径l,我们可以把它先设为未知量l
对于走回原点次数,可以手算模拟一遍,当l为1,环长度为6,总共需要6次
当l为2,需要3次,当l为3,需要2次,而l为4次时,需要3次,l为5次时,需要6次
由此我们可看出规律,得出公式:t=(n*k)/gcd(n*k,l)
接下来我们再来求l,我们可以推导出l=m+c
m我们讨论一下
对1 0 0 0 0 1 0 0 0 0 1 0 0 0 0
给出的数据时k=5,a=2,b=1;
a=1,b=2时,l是1,2,4,7
a=1,b=1时,l是0,3,5,8
可猜测l分别为|a-b|,k-a-b,k-a+b,2k-a-b
c为k的倍数,只需要枚举下从0到n的k倍数即可
#pragma GCC optimize(2) #pragma GCC optimize(1) #include<bits/stdc++.h> typedef long long ll; typedef unsigned long long ull; const ull base=131; #define MAX 100009 #define PI 3.141592653589793 using namespace std; int main() { std::ios::sync_with_stdio(false); std::cin.tie(0);std::cout.tie(0); ll n,k,a,b; cin>>n>>k>>a>>b; ll circle=n*k,L[4]={abs(a-b),k-a-b,k-a+b,2*k-a-b}; ll mx = LLONG_MIN, mi = LLONG_MAX; for(ll i=0;i<4;i++){ ll temp=L[i]; for(ll j=0;j<n;j++,temp+=k){ mx=max(mx,abs(__gcd(circle,temp))); mi=min(mi,abs(__gcd(circle,temp))); } } cout<<circle/mx<<' '<<circle/mi<<"\n"; }