zoukankan      html  css  js  c++  java
  • 1786. 韩信点兵

    ★★★   输入文件:HanXin.in   输出文件:HanXin.out   简单对比

    时间限制:1 s   内存限制:256 MB

    【题目描述】

        韩信是中国军事思想“谋战”派代表人物,被后人奉为“兵仙”、“战神”。“王侯将相”韩信一人全任。“国士无双”、“功高无二,略不世出”是楚汉之时人们对其的评价。作为统帅,他率军出陈仓、定三秦、擒魏、破代、灭赵、降燕、伐齐,直至垓下全歼楚军,无一败绩,天下莫敢与之相争。

        相传,韩信带兵打仗时,从不直接清点军队人数。有一次,韩信带1500名兵士打仗,战死四五百人。站3人一排,多出2人;站5人一排,多出4人;站7人一排,多出6人。韩信马上说出人数:1049。

        这次,刘邦派韩信带兵N人攻打一座重兵驻扎的城市。城市占领了,可汉军也是伤亡惨重。韩信需要知道汉军至少损失了多少兵力,好向刘邦汇报。

        已知韩信发出了M次命令,对于第i次命令,他选择一个素数Pi,要求士兵每Pi人站一排,此时最后一排剩下了ai人。你的任务是帮助韩信求出这种情况下汉军损失兵力的最小值。当然,由于士兵们都很疲惫,他们有可能站错队伍导致韩信得到的数据有误。

    【输入格式】

    第一行两个正整数N,M,分别代表最初的军队人数和韩信的询问次数。

    接下来有M行,每行两个非负整数Piai,代表韩信选择的素数和此时剩下的人数。

    输入保证每个素数各不相同。

    【输出格式】

    输出一行,一个整数。

    若有解,输出最小损失人数。若无解,输出-1.

    【样例输入】

    1500 3
    3 2
    5 4
    7 6
    
    

    【样例输出】

    31
    
    

    【数据范围】

    30%,1N1,000,000,1M4;

    50%1N100,000,000,1M8;

    100%1N1,000,000,000,000,1M10;1012,0ai<Pi.

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #define N 20
    #define LL long long 
     
    using namespace std;
    LL n,m,a[N],p[N],mod;
     
    void exgcd(LL a,LL b,LL &x,LL &y)
    {
        if (!b) 
    	{
            x=1; y=0;
            return;
        }
        exgcd(b,a%b,x,y);
        LL t=y;
        y=x-(a/b)*y;
        x=t;
    }
     
    LL china()
    {
        LL ans=0;
        for (int i=1;i<=m;i++) 
    	{
            LL mi=mod/p[i];
            LL x,y;
            exgcd(mi,p[i],x,y);
            ans=(ans+mi*x*a[i])%mod;
        }
        return (ans%mod+mod)%mod;
    }
     
    int main()
    {   
    	freopen("HanXin.in","r",stdin);
    	freopen("HanXin.out","w",stdout); 
        scanf("%lld%lld",&n,&m); 
    	mod=1;
        for (int i=1;i<=m;i++) 
    		scanf("%lld%lld",&p[i],&a[i]),
    		mod*=p[i];//所有模数的乘积 
    		
        LL ans=china();// cout<<ans<<endl;
        
        if (ans>n) 
    	{
            printf("-1
    ");
            return 0;
        }
        
        LL t=(n-ans)/mod*mod;
        ans=n-ans-t; 
        printf("%lld
    ",(ans%mod+mod)%mod);
        return 0;
    }
     
     
     
     
     
    

      

  • 相关阅读:
    BZOJ 2956: 模积和
    BZOJ 1113: [Poi2008]海报PLA
    停课刷题总结-给自己一点鼓励吧
    BZOJ 2751: [HAOI2012]容易题(easy)
    Vijos 1100 加分二叉树
    BZOJ 1756: Vijos1083 小白逛公园
    BZOJ 1709: [Usaco2007 Oct]Super Paintball超级弹珠
    BZOJ 1652: [Usaco2006 Feb]Treats for the Cows
    BZOJ 1651: [Usaco2006 Feb]Stall Reservations 专用牛棚
    BZOJ 1631: [Usaco2007 Feb]Cow Party
  • 原文地址:https://www.cnblogs.com/lyqlyq/p/7327617.html
Copyright © 2011-2022 走看看