zoukankan      html  css  js  c++  java
  • Mail.Ru Cup 2018 Round 2 C. Lucky Days(拓展欧几里得)

    传送门

    待参考资料:

      [1]:https://www.cnblogs.com/Patt/p/9941200.html

    •题意

      a君,b君存在幸运周期;

      a君在第[ L1+k·t1,R1+k·t1]天为幸运天;

      b君在第[ L2+k·t2,R2+k·t2]天为幸运天;

      求 a君,b君 同为幸运天数的最大的连续天数;

    题解

      a君所有幸运天数开始的时刻为 La = L1+x·t1

      b君所有幸运天数开始的时刻为 Lb = L2+y·t2

      假设 a君 每个周期幸运的天数为 lena , b君的为 lenb

      ①如果 ∃ x,y 使得 La = Lb ,那么答案就是 min(lena,lenb);

      ②反之,根据贪心策略,两者的幸运天数开始越接近,那么两者的公共幸运天数就越多;

       也就是说,找到最小的非负整数 d1 使得 La + d1 = Lb 或最小的非负整数 d2 使得 La = Lb+d2; 

      如何判断①是否成立呢?

        根据拓展欧几里得,使得①成立当且仅当 GCD(t1,t2)  |  |Lb-La|;

      如果不成立,如何找到最小的d1,d2呢?

      

      由 ①② 可得 b1 = (L2-L1)%GCD(t1,t2),并且要确保 b1 > 0;

      同理可求b2

    •Code

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define GCD(a,b) __gcd(a,b)
     4 #define ll long long
     5 
     6 ll l1,r1,t1;
     7 ll l2,r2,t2;
     8 
     9 ll Solve()
    10 {
    11     if(abs(l2-l1)%GCD(t1,t2) == 0)
    12         return min(r1-l1+1,r2-l2+1);
    13 
    14     ll d1=(l2-l1)%GCD(t1,t2);
    15     if(d1 < 0)
    16         d1 += GCD(t1,t2);
    17 
    18     ll d2=(l1-l2)%GCD(t1,t2);
    19     if(d2 < 0)
    20         d2 += GCD(t1,t2);
    21 
    22     ///两者幸运天数无交集时,取min时会返回负数,所以需要对0取个max
    23     return max(1ll*0,max(min(r1-l1-d1+1,r2-l2+1),min(r1-l1+1,r2-l2-d2+1)));
    24 }
    25 int main()
    26 {
    27     scanf("%lld%lld%lld",&l1,&r1,&t1);
    28     scanf("%lld%lld%lld",&l2,&r2,&t2);
    29     printf("%lld
    ",Solve());
    30 
    31     return 0;
    32 }
    View Code
  • 相关阅读:
    图解C/C++多级指针与多维数组
    排序---选择排序
    排序---插入排序
    排序---希尔排序
    Merge Two Sorted Lists
    Remove Nth Node From End of List
    如何阅读Django文档?
    机器学习 第一章 绪论 笔记
    python工程实践·笔记
    Python后端开发面经
  • 原文地址:https://www.cnblogs.com/violet-acmer/p/10878200.html
Copyright © 2011-2022 走看看