COGS——T 1786. 韓信點兵
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行,每行兩個非負整數Pi,ai,代表韓信選擇的素數和此時剩下的人數。
輸入保證每個素數各不相同。
【輸出格式】
輸出一行,一個整數。
若有解,輸出最小損失人數。若無解,輸出-1.
【樣例輸入】
1500 3 3 2 5 4 7 6
【樣例輸出】
31
【數據範圍】
對於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;保證所有素數的乘積≤1012,0≤ai<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. 韓信點兵