D. The Beatles(思维+枚举)

D. The Beatles

 

题意:

有n*k个城市,每个城市间的距离是1km,在第1,1+k,1+k*2……,1+(n-1)*k个城市中有饭馆,

从城市s出发,每次走过的距离为l,问再次回到s时停了多少站,数量为num,第一次在s不算。

已知在s时离s最近的饭店的距离是a,当走过l后距离最近的饭店的距离是b,已知走的顺序有两种,分为顺时针,逆时针。

求最小的num = x,最大的num = y。

 

思路:

一开始题目都没读懂 ̄□ ̄||,后来参考别人的代码,先考虑顺时针和逆时针两种情况,

顺时针:(1)s-1 = a,(2)s-1+l = b

逆时针:(1)s-1 = -a,(2) s-1+l = -b。

所以总共四种情况。

将1,2组合得到l的四种情况

a+b,a-b,b-a,-a-b。

l的间距一定是正数,而且肯定大于k,所以可以写成l = k*i+c的形式,

然后枚举i,i的范围是1~n,c肯定是[1,k)范围内,所以对k取余即可。

从s出发经过n*k/gcd(n*k,l),次回到s,所以枚举所有情况就能求出最终的最小次数和最大次数。

 

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn = 100100;
typedef long long LL;
LL MIN(LL x,LL y){
	return x<y?x:y;
}
LL MAX(LL x,LL y){
	return x>y?x:y;
}
LL Gcd(LL x,LL y){
	return y==0?x:Gcd(y,x%y);
}
int main(void)
{
	LL n,k,a,b,i,j;
	scanf("%lld%lld%lld%lld",&n,&k,&a,&b);
	LL f[4];
	f[0] = a+b;
	f[1] = a-b;
	f[2] = -a+b;
	f[3] = -a-b;
	LL x = 1e18+5,y = -1;
	for(i=0;i<n;i++){
		for(j=0;j<4;j++){
			LL c = (f[j]+k)%k;
			LL tp = (i*k+c);
			x = MIN(x,n*k/Gcd(n*k,tp));
			y = MAX(y,n*k/Gcd(n*k,tp));
		}
	}
	printf("%lld %lld\n",x,y);
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值