《第二届太原理工大学程序设计新生赛决赛》E
可以发现,对于从右开始的操作。
可以看成从左边某个点开始不断向右加b的操作。
那么显然可以发现左边开始的点为n%b+1.
那么我们找到a,b第一次遇到的情况。这时是第一个左右手都有糖的人。
那么我们又可以发现,从这点开始,他们俩下次遇到的情况,显然是+lcm(a,b).
即从这点开始每隔lcm(a,b)相遇一次。
那么剩下的点长度为n-开始跳的点。这个长度内可以有多少个lcm(a,b)就是他们的相遇的个数。
即(n-low)/lcm(a,b)。注意加上一开始相遇的点。
Code:
#include<bits/stdc++.h> using namespace std; typedef long long LL; typedef pair<int,int> pii; const int N = 2e5+5; const int M = 1e6+5; const int Mod = 1e9+7; #define pi acos(-1) #define INF 1e18 #define INM INT_MIN #define rg register #define pb(a) push_back(a) #define mk(a,b) make_pair(a,b) #define dbg(x) cout << "now this num is " << x << endl; #define met0(axx) memset(axx,0,sizeof(axx)); #define metf(axx) memset(axx,-1,sizeof(axx)); #define sd(ax) scanf("%d",&ax) #define sld(ax) scanf("%lld",&ax) #define sldd(ax,bx) scanf("%lld %lld",&ax,&bx) #define sdd(ax,bx) scanf("%d %d",&ax,&bx) #define sddd(ax,bx,cx) scanf("%d %d %d",&ax,&bx,&cx) #define sfd(ax) scanf("%lf",&ax) #define sfdd(ax,bx) scanf("%lf %lf",&ax,&bx) #define pr(a) printf("%d\n",a) #define plr(a) printf("%lld\n",a) LL Lcm(LL x,LL y) { return x/__gcd(x,y)*y;//先除后乘防止爆longlong } void run() { LL n,a,b; cin >> n >> a >> b; LL low; for(LL i = n%b+1;i <= n;i += b) { if(i%a == 0){low = i;break;} } if(low > n) printf("0\n"); else { LL ans = (n-low)/Lcm(a,b)+1; plr(ans); } } int main() { run(); //system("pause"); return 0; }