【牛客多校】Han Xin and His Troops

題目:java

His majesty chatted with Han Xin about the capabilities of the generals. Each had their shortcomings. His majesty asked, ``How many troops could I lead?" Han Xin replied, ``Your highness should not lead more than 100000." His majesty said, ``And what about you?" ``For your humble servant, the more the merrier!" said Han Xin.

---Records of the Grand Historian

Han Xin was a military general who served Liu Bang during the Chu-Han contention and contributed greatly to the founding of the Han dynasty. Your friend, in a strange coincidence, also named Han Xin, is a military general as well.

One day you asked him how many troops he led. He was reluctant to tell you the exact number, but he told you some clues in certain form, for example:ios

- if we count the troops by threes, we have two left over;
- if we count by fives, we have three left over;
- if we count by sevens, two are left over;
- ...
You wonder the number of his troops, or he was simply lying. More specifically, you would like to know the minimum possible number of troops he leads, and if the minimum number is too large, then you suspect he was lying.

連接:https://ac.nowcoder.com/acm/contest/890/D
來源:牛客網ide

示例1

輸入

3 100
3 2
5 3
7 2

輸出

23
示例2

輸入

4 10000
12 7
15 2
30 5
8 6

輸出

he was definitely lying
示例3

輸入

2 10
11 3
19 7

輸出

he was probably lying


題目大意:韓信點兵,給你n個結果,兵隊總數%ai=bi,而後求出最後兵隊最少到底有多少人。
若是這個數不存在,輸出
he was definitely lying
若是數量大於給定的門檻m,輸出he was probably lying,不然出輸出人數。
題解:由於最後的餘數並非徹底互質,因此須要使用擴展中國剩餘定理。
還有一個坑,就是這些餘數可能徹底互質,因此最後的M會特別特別大,
我以前使用的是洛谷中國剩餘定理模板題的第一個模板,就是由於M特別大,
改寫成了java,用大數作就過了。寫的有點醜,不要介意。
import java.util.*;
import java.math.*;
import java.security.MessageDigest;
 
public class Main {
    static int n;
    static BigInteger m,x,y;
    static BigInteger[] ai=new BigInteger[200];
    static BigInteger[] bi=new BigInteger[200];
    public static void main(String[] args) {
        Scanner cin=new Scanner(System.in);
        n=cin.nextInt();
        m=cin.nextBigInteger();
        for(int i=1;i<=n;i++)
        {
            bi[i]=cin.nextBigInteger();
            ai[i]=cin.nextBigInteger();
        }
        BigInteger ans = excrt();
        long flag=-1;
        if (ans.compareTo(BigInteger.valueOf(flag))==0)
                System.out.print("he was definitely lying\n");
        else if(ans.compareTo(m)!=-1&&ans.compareTo(m)!=0)
            System.out.print("he was probably lying\n");
        else System.out.print(ans);
    }
     
    public static BigInteger excrt()
    {
        BigInteger k;
        BigInteger ans = ai[1];
        BigInteger M=bi[1];
        for (int i = 2; i <= n; i++)
        {
            BigInteger a = M, b = bi[i];
            BigInteger c=ai[i].subtract(ans.mod(b)).add(b).mod(b);
            BigInteger gcd = exgcd(a, b), bg = b .divide(gcd);
            long flag=-1;
            if (c.mod(gcd).compareTo(BigInteger.ZERO)!=0) return BigInteger.valueOf(flag);
      
            x = mul(x,c.divide(gcd), bg);
            ans=ans.add(x.multiply(M));
            M =M.multiply(bg);
            ans = (ans.mod(M).add(M)).mod(M);
        }
        return (ans.mod(M).add(M)).mod(M);
    }
     
    public static BigInteger mul(BigInteger a, BigInteger b, BigInteger mod)
    {
        BigInteger res = BigInteger.ZERO;
        while (b.compareTo(BigInteger.ZERO)>0)
        {
            if (b.mod(BigInteger.valueOf((long)2)).compareTo(BigInteger.ZERO)>0) res = res.add(a).mod(mod);
            a = a.add(a).mod(mod);
            b = b.divide(BigInteger.valueOf((long)2));
        }
        return res;
    }
      
    public static BigInteger exgcd(BigInteger a, BigInteger b)
    {
        if (b.compareTo(BigInteger.ZERO)==0)
        {
            x = BigInteger.ONE; y = BigInteger.ZERO;
            return a;
        }
        BigInteger gcd = exgcd(b, a.mod(b));
        BigInteger tp = x;
        x = y; y = tp.subtract(a.divide(b).multiply(y));
        return gcd;
    }
}
 
    

  

貼一下洛谷模板題:https://www.luogu.org/problem/P4777oop

模板來源:https://blog.csdn.net/niiick/article/details/80229217spa

C++模板代碼:.net

//niiick
#include<iostream>
#include<vector>
#include<algorithm>
#include<queue>
#include<cstring>
#include<cstdio>
using namespace std;
typedef long long lt;

lt read()
{
    lt f=1,x=0;
    char ss=getchar();
    while(ss<'0'||ss>'9'){if(ss=='-')f=-1;ss=getchar();}
    while(ss>='0'&&ss<='9'){x=x*10+ss-'0';ss=getchar();}
    return f*x;
}

const int maxn=100010;
int n;
lt ai[maxn],bi[maxn];

lt mul(lt a,lt b,lt mod)
{
    lt res=0;
    while(b>0)
    {
        if(b&1) res=(res+a)%mod;
        a=(a+a)%mod;
        b>>=1;
    }
    return res;
}

lt exgcd(lt a,lt b,lt &x,lt &y)
{
    if(b==0){x=1;y=0;return a;}
    lt gcd=exgcd(b,a%b,x,y);
    lt tp=x;
    x=y; y=tp-a/b*y;
    return gcd;
}

lt excrt()
{
    lt x,y,k;
    lt M=bi[1],ans=ai[1];//第一個方程的解特判
    for(int i=2;i<=n;i++)
    {
        lt a=M,b=bi[i],c=(ai[i]-ans%b+b)%b;//ax≡c(mod b)
        lt gcd=exgcd(a,b,x,y),bg=b/gcd;
        if(c%gcd!=0) return -1; //判斷是否無解,然而這題其實不用

        x=mul(x,c/gcd,bg);
        ans+=x*M;//更新前k個方程組的答案
        M*=bg;//M爲前k個m的lcm
        ans=(ans%M+M)%M;
    }
    return (ans%M+M)%M;
}

int main()
{
    n=read();
    for(int i=1;i<=n;++i)
    bi[i]=read(),ai[i]=read();
    printf("%lld",excrt());
    return 0;
}
View Code
相關文章
相關標籤/搜索