您的位置:首页 > 其它

关于 中国剩余定理 的两道水题练手

2017-08-10 08:06 477 查看

51Nod 1079 中国剩余定理

一个正整数K,给出K Mod 一些质数的结果,求符合条件的最小的K。例如,K % 2 = 1, K % 3 = 2, K % 5 = 3。符合条件的最小的K = 23。

Input

第1行:1个数N表示后面输入的质数及模的数量。(2 <= N <= 10)

第2 - N + 1行,每行2个数P和M,中间用空格分隔,P是质数,M是K % P的结果。(2 <= P <= 100, 0 <= K < P)

Output

输出符合条件的最小的K。数据中所有K均小于10^9。

Input示例

3

2 1

3 2

5 3

Output示例

23

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>

using namespace std;
#define LL long long
LL a[100],m[100]; int n;
LL M=1;
void EXGCD(LL a,LL b,LL &x,LL &y){
if(!b){
x=1; y=0; return ;
}
EXGCD(b,a%b,x,y);
int tmp=x; x=y;
y=tmp-(a/b)*y;
}
LL CRT(LL a[],LL m[],int n){
LL ans=0;
for(int i=1;i<=n;i++){
LL x,y;
LL Mi=M/m[i];
EXGCD(Mi,m[i],x,y);
ans=(ans+Mi*x*a[i])%M;
}
if(ans<0) ans+=M;
return ans;
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d%d",&m[i],&a[i]);
M*=m[i];
}
LL ans=CRT(a,m,n);
printf("%lld\n",ans);
return 0;
}


COGS 1786. 韩信点兵

时间限制: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

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#define LL long long
using namespace std;
LL n,T,a[15],m[15],M=1;
void EXGCD(LL a,LL b,LL &x,LL &y){
if(!b){ x=1;y=0;return; }
EXGCD(b,a%b,x,y);
int tmp=x;x=y;
y=tmp-(a/b)*y;
}
LL CRT(){
LL ans=0;
for(int i=1;i<=T;i++){
LL x,y,Mi=M/m[i];
EXGCD(Mi,m[i],x,y);
ans=(ans+Mi*x*a[i])%M;
}
return ans;
}
int main(){
//freopen("HanXin.in","r",stdin);
//freopen("HanXin.out","w",stdout);
scanf("%lld%lld",&n,&T);
for(int i=1;i<=T;i++){
scanf("%lld%lld",&m[i],&a[i]);
M*=m[i];
}
LL ans=CRT();
if(ans>n){
printf("-1");
return 0;
}
while(ans+M<=n) ans+=M;
printf("%lld\n",n-ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  中国剩余定理