zoukankan      html  css  js  c++  java
  • 小凯的疑惑 / [蓝桥杯2013省]买不到的数目

    题面

         点这里

             大意是正整数a,b互素,求最大的k,使得ax+by=k(x>=0,y>=0)无解,即不能用a,b凑出k。

    思路

         根据上面提取出的公式,可以很快联想到exgcd求不定方程,实际上这也确实是一种解法,但本人太菜,选择了一种更为通俗的方法:

       ........本文中将一个数能被凑出称为被覆盖..........

                不妨设b>a, 将实数数轴划分为长度为a的若干段,则每段中至多有一个b的倍数,显然对于x=c1*a+c2*b来说,c1的大小不影响x在所属段中的相对位置。只有c2即b的个数会影响其位置,而对数轴上的某一个位置来说,只要在当前段中能被凑出,以后每一段中的此位置都可以通过+a被覆盖。问题转化为求第一个将长度为a的数段完全覆盖的位置。设加入x=c3*b后,该段能被完全覆盖,则x'=x-a位置一定未被覆盖。且x'所在段中其他数一定已被覆盖。所以x'即为所求。

         可以发现b的个数每增加1,就会覆盖段中的一个新位置(如果覆盖的是旧的位置,而此时此段还未被完全覆盖,那么b的覆盖位置会形成一个循环,此题即无解,对应的是a,b不互质的情况)当q*b%a==0时,x1=n*b与x2=(n+q)*b在段中的相对位置相同,当q最小时,q=a/(gcd(a,b),因此第一个重复的位置一定是a/(gcd(a,b)*b)。a,b互质时,第一个重复位置即为a*b。所以第一个完全覆盖的位置为x=(a-1)*b。因此x'=x-a=a*b-a-b。至此可以O(1)得出答案。

               也可以换一种思路感性理解:因为每次覆盖的位置不同,长度为a的段要覆盖a次,因为0*b也算一次,所以最大的位置为x=(a-1)*b,x'=x-a=a*b-a-b。

               建议不必看代码了。

     1 #include<bits/stdc++.h>
     2 #define ll long long
     3 #define pi pair<int,int>
     4 using namespace std;
     5 int main(){
     6     int i,j,n,m;
     7     ll k,l;
     8     scanf("%lld%lld",&k,&l);
     9     k=k*l-k-l;
    10     printf("%lld",k);
    11     return 0;
    12 }
    View Code
  • 相关阅读:
    种类并查集
    51nod 1241 特殊的排序(动态规划)
    NKU 专题一 题解
    51nod 1040 最大公约数之和
    cf #419(div2) C.Karen and Game(贪心)
    BZOJ 2648 SJY摆棋子(KD-Tree)
    BZOJ 4154 [Ipsc2015]Generating Synergy(KD-Tree)
    hdu 2966 In case of failure(KD-tree)
    hdu 6071 Lazy Running(同余最短路)
    hdu 6070 Dirt Ratio(分数规划)
  • 原文地址:https://www.cnblogs.com/jstcao/p/14041445.html
Copyright © 2011-2022 走看看