1. 程式人生 > >COGS——T 1786. 韓信點兵

COGS——T 1786. 韓信點兵

一行 pan += exgcd 出了 problem 選擇 href n-2

http://www.cogs.pro/cogs/problem/problem.php?pid=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.

 1 #include <algorithm>
 2 #include <cstdio>
 3 
 4 using namespace std;
 5 
 6 #define LL long long
 7 LL n,m,p[23],a[23],tot=1;
 8 
 9 void exgcd(LL a,LL b,LL &x,LL &y)
10 {
11     if(!b) { x=1; y=0; return ; }
12     exgcd(b,a%b,x,y);
13     LL tmp=x; x=y; y=tmp-a/b*x;
14 }
15 LL CRT()
16 {
17     LL ret=0;
18     for(int i=1;i<=m;i++)
19     {
20         LL t=tot/p[i],x,y;
21         exgcd(t,p[i],x,y);
22         ret=(ret+t*x*a[i])%tot;
23     }
24     return ret>=0?ret:ret+tot;
25 }
26 
27 int main()
28 {
29     freopen("HanXin.in","r",stdin);
30     freopen("HanXin.out","w",stdout);
31     
32     scanf("%lld%lld",&n,&m);
33     for(int i=1;i<=m;i++)
34         scanf("%lld%lld",p+i,a+i),tot*=p[i];
35     LL ans=CRT();
36     if(ans>n)
37     {
38         printf("-1");
39         return 0;
40     }
41     for(;ans+tot<=n;) ans+=tot;
42     printf("%lld",n-ans);
43     return 0;
44 }

COGS——T 1786. 韓信點兵