《第二届太原理工大学程序设计新生赛决赛》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;
}

 

posted @ 2020-06-15 14:08  levill  阅读(199)  评论(0编辑  收藏  举报