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

    P1272 - 韩信点兵

    Description

    韩信是中国军事思想“谋战”派代表人物,被后人奉为“兵仙”、“战神”。“王侯将相”韩信一人全任。“国士无双”、“功高无二,略不世出”是楚汉之时人们对其的评价。作为统帅,他率军出陈仓、定三秦、擒魏、破代、灭赵、降燕、伐齐,直至垓下全歼楚军,无一败绩,天下莫敢与之相争。
    相传,韩信带兵打仗时,从不直接清点军队人数。有一次,韩信带1500名兵士打仗,战死四五百人。站3人一排,多出2人;站5人一排,多出4人;站7人一排,多出6人。韩信马上说出人数:1049。
    这次,刘邦派韩信带兵N人攻打一座重兵驻扎的城市。城市占领了,可汉军也是伤亡惨重。韩信需要知道汉军至少损失了多少兵力,好向刘邦汇报。
    已知韩信发出了M次命令,对于第i次命令,他选择一个素数Pi,要求士兵每Pi人站一排,此时最后一排剩下了aiai 人。你的任务是帮助韩信求出这种情况下汉军损失兵力的最小值。当然,由于士兵们都很疲惫,他们有可能站错队伍导致韩信得到的数据有误。

    Input

    第一行两个正整数N,M,分别代表最初的军队人数和韩信的询问次数。
    接下来有M行,每行两个非负整数$Pi, ai$,代表韩信选择的素数和此时剩下的人数。
    输入保证每个素数各不相同。

    Output

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

    Sample Input

    1500 3
    3 2
    5 4
    7 6

    Sample Output

    31

    Hint

    对于30%的数据,1≤N≤1,000,000,1≤M≤4;
    对于50%的数据,1≤N≤100,000,000,1≤M≤8;
    对于100%的数据,1≤N≤1,000,000,000,000,1≤M≤10;保证所有素数的乘积≤10121012 , 0≤ai≤Pi.

    Source

    数论,欧几里得,中国剩余定理

     
    扩展欧几里得
     
     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstdlib>
     4 #include <cstring>
     5 #include <algorithm>
     6 #define  ll long long
     7 using namespace std;
     8 const int N=1001;
     9 ll m[N],r[N];
    10 int n;
    11 ll gcd(ll a,ll b) {
    12     return a%b==0 ? b : gcd(b,a%b);
    13 }
    14 void exgcd(ll a,ll b,ll& x,ll& y) {
    15     if(!b) x=1,y=0;
    16     else {
    17         exgcd(b,a%b,x,y);
    18         ll tmp=x;
    19         x=y;
    20         y=tmp-a/b*y;
    21     }
    22 }
    23 ll solve() {
    24     ll M=m[1],R=r[1];
    25     for(int i=2;i<=n;i++) {
    26         ll d=gcd(M,m[i]);    
    27         ll c=r[i]-R;
    28         if(c%d) return -1;
    29         ll k1,k2;
    30         exgcd(M/d,m[i]/d,k1,k2);
    31         k1=(c/d*k1) % (m[i]/d);
    32         R=R+k1*M;
    33         M=M/d*m[i];
    34         R%=M;
    35     }
    36     while    (R<=0) R+=M;
    37     return R;
    38 }
    39 int main() {
    40     
    41     cin>>n;
    42     for(int i=1;i<=n;i++) cin>>m[i]>>r[i];
    43     printf("%lld",solve());
    44     return 0;
    45     
    46 }
  • 相关阅读:
    解析XML技术
    XML名命空间
    XML解析器
    java列表组件鼠标双击事件的实现
    XML(可拓展标记语言)基本概念
    数据包式套接字:基于UDP协议的Socket网络编程
    流式套接字:基于TCP协议的Socket网络编程(案例3)
    剑指 Offer 58
    剑指 Offer 58
    剑指 Offer 57
  • 原文地址:https://www.cnblogs.com/ypz999/p/6657196.html
Copyright © 2011-2022 走看看