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行,每行两个非负整数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 }

 

posted @ 2017-08-10 06:40  Aptal丶  阅读(240)  评论(0编辑  收藏  举报