[HDU3579] Hello Kiki

来源:互联网 发布:软件行业 互联网行业 编辑:程序博客网 时间:2024/05/21 10:45

题目描述

Kiki是个可爱的女孩,她喜欢用不同的方式计数,比如:Kiki现在有X个硬币,她用不同的方式数了N次,每次她想都把硬币分成大小相等的组,并记录组数Mi和剩余的硬币数Ai。
一天Kiki的爸爸想知道硬币的数目,于是他查看了Kiki的记录,但是他迷茫了,聪明的你能帮帮他么?


输入格式

第一行输入测试数据的组数T,接下来有T组测试数据:每组测试数据包括三行:第一行为N,第二行是N个整数Mi,第三行对应N个整数Ai,其中1≤T≤100,1≤N≤6,1≤Mi≤50,0≤Ai

输出格式

对应每组测试数据输出最小的正整数解,若无解,则输出-1,若同余方程组的解为0,则输出Mi的最小公倍数。


样例数据

样例输入

2
2
14 57
5 56
5
19 54 40 24 80
11 2 36 20 76

样例输出

Case 1: 341
Case 2: 5996


题目分析

裸题,见源代码
扩展欧几里得解线性方程组


源代码

#include<algorithm>#include<iostream>#include<iomanip>#include<cstring>#include<cstdlib>#include<vector>#include<cstdio>#include<cmath>#include<queue>using namespace std;inline const long long Get_Int() {    long long num=0,bj=1;    char x=getchar();    while(x<'0'||x>'9') {        if(x=='-')bj=-1;        x=getchar();    }    while(x>='0'&&x<='9') {        num=num*10+x-'0';        x=getchar();    }    return num*bj;}long long Exgcd(long long a,long long b,long long &x,long long &y) {    if(b==0) {        x=1;        y=0;        return a;    }    long long ans=Exgcd(b,a%b,x,y),tmp=x;    x=y;    y=tmp-a/b*y;    return ans;}long long n,a[5005],r[5005];void Solve(int num) {    long long a1=a[1],r1=r[1];    for(int i=2; i<=n; i++) {        long long a2=a[i],r2=r[i],a=a1,b=a2,c=r2-r1,x0,y0;        long long gcd=Exgcd(a,b,x0,y0);        if(c%gcd) { //无解            printf("Case %d: -1\n",num);            return;        }        long long b1=b/gcd;        x0=(x0*(c/gcd)%b1+b1)%b1;        r1+=a1*x0; //带入原方程组的第一个        a1*=(a2/gcd);     }    if(r1==0)printf("Case %d: %lld\n",num,a1);    else printf("Case %d: %lld\n",num,r1);}int t;int main() {    t=Get_Int();    for(int i=1; i<=t; i++) {        n=Get_Int();        for(int j=1; j<=n; j++)a[j]=Get_Int();        for(int j=1; j<=n; j++)r[j]=Get_Int();        Solve(i);    }    return 0;}

0 0
原创粉丝点击