码迷,mamicode.com
首页 > 其他好文 > 详细

露娜养佩奇

时间:2018-03-04 23:51:39      阅读:241      评论:0      收藏:0      [点我收藏+]

标签:中国剩余定理   nes   它的   mil   次数   type   []   strong   代码   

【题目背景】

露娜的好朋fu友qin猪哥哥是一个屌丝科学家,他发明出了一个可以进行空间跳跃的机器,露娜将作为第一个乘客进行时空跳跃之旅。她将地点定位于佩奇的家。嗖!

露娜来到佩奇的家中,佩奇一家热情地招待了她,她在佩奇家愉快地玩耍,这期间还学会了花样跳泥坑,种恐龙。时光荏苒,很快到了露娜返程的日子。她提取了佩奇的基因,猪哥哥帮助她克隆出了许多佩奇。

露娜的另一个好朋er友zi——精致的猪猪女孩萝萝,也是一个喜欢佩奇的人,有一天,她来参观露娜的佩奇欢乐草原,并且想知道这里佩奇的数量。但是由于萝萝是一个快要进国大的女孩,露娜想出一道题考考她,看看萝萝是否有资质将露娜带飞。

【题目描述】

举个例子,假如有16只佩奇,如果建了3个小屋,剩下1只佩奇就没有地方安家了。如果建造了5个小屋,但是仍然有1只佩奇没有地方去,然后如果建造了7个小屋,还有2只佩奇没有地方去。萝萝思考了一会,得出了答案!

 

输入

 

第一行包含一个整数n (n <= 10) – 建立小屋的次数,解下来n行,每行两个整数ai, bi( bi <= ai <= 1000), 表示建立了ai个小屋,有bi只佩奇没有去处。你可以假定ai,aj互质.

 

输出

 

输出包含一个正整数,即为露娜至少养佩奇的数目。

 

样例输入

 

3

 

3 1

 

5 1

 

7 2

 

样例输出

 

16

【胡乱分析】

尽管题目描述的天花乱坠,但板子题就是板子题。

这道题涉及到了数论基础中的一些内容,下面进行讲解与证明。(巨佬就别看了。。。)

[exgcd]

对于a,b(a>b)一定存在整数x,y使得xa+yb=gcd(a,b)

(1)当b为0时,gcd(a,b)=a。此时有x=1,y=0;

(2)当a>b>0时,

设ax1+by1=gcd(a,b)

bx2+(a%b)y2=gcd(b,a%b)

∵gcd(a,b)=gcd(b,a%b)

∴ax1+by1=bx2+(a%b)y2

∵a%b=(a-[a/b]y2)

∴ax1+by1=bx2+(a-[a/b]*b)y2

∴ax1+by2=bx2+ay2-[a/b]*by2

∴ax1+by2=ay2+b(x2-[a/b]*y2)

即得x1=y2,y1=x2-[a/b]*y2。

如果c|gcd(a,b)则ax+by=c一定有整数解。

代码如下

 1 int exgcd(long long a,long long b,long long &x,long long &y)
 2 {
 3     if(b==0)
 4     {
 5         x = 1;
 6         y = 0;
 7         return a;
 8     }
 9     int d = exgcd(b,a%b,y,x)
10     y-=a/b*x;
11     return d;
12 }

然后是中国剩余定理。这个代码我没弄太懂也只能背板子了。那么它的思路就是,,,就是,,,就是,,

求x满足x%3 == 2;x%5==3;x%7==2; 令x1=k*lcm(5,7)使得x1%3==1,同理x2 = k*lcm(3,7)  x2%5==1,  x3 = k*lcm(3,5)  x3%7==1,(k∈N*)则x=(x1*2+x2*3+x3*2)%(3*5*7)。

对于上述操作一些有疑问的地方的讲解:x=(x1*2+x2*3+x3*2)%(3*5*7)中的2,3,2,分别对应着那些余数,这里用到一个定理(还是推理)是”如果a%b=c 那么(a*k)%b=kc“。这样大家就懂了叭。

那么它的板子如下

 1 //中国剩余定理 ,r[]存放余数 ,prime[]存放两两互质的数  
 2 int Chinese_Remainder(int r[],int prime[],int len)  
 3 {  
 4     int i,d,x,y,m,n=1,sum=0;  
 5     //计算所以除数的积n,也是所以除数的最小公倍数  
 6     for(i=0;i<len;i++)  
 7         n*=prime[i];  
 8     //计算符合所以条件的数  
 9     for(i=0;i<len;i++)  
10     {  
11         m=n/prime[i];//计算除去本身的所有除数的积m  
12         d=exgcd(prime[i],m,x,y);//计算w[i]*x+m*y=gcd(w[i],m)的一个解y  
13         //累加整数解y的同并不断对n取余,其利用公式:(a+b)%c=(a%c+b%c)%c  
14         sum=(sum+y*m*r[i])%n;  
15     }  
16     return (n+sum%n)%n;//满足所以方程的最小解  
17 }  

从某神ben那里巴拉来的。

然后这是gg给的标程

 1 #include<iostream>
 2 #include<cstdio>
 3 using namespace std;
 4 #define N 5050
 5 typedef long long LL;
 6 LL m[N];
 7 LL M=1,n,ans;
 8 LL t[N],Mn[N],MM[N];
 9  
10 LL exgcd(LL a,LL b,LL &x,LL &y)
11 {
12     if(b==0)
13     {
14         x=1,y=0;return a;
15     }
16     else
17     {
18         LL t=exgcd(b,a%b,y,x);
19         y-=x*(a/b);
20         return t;
21     }
22 }
23  
24 LL CRT()
25 {
26     LL temp;
27     for(LL i=1;i<=n;i++)
28     {
29         MM[i]=M/m[i];
30         LL k=exgcd(MM[i],m[i],Mn[i],temp);
31         ans+=(MM[i]*Mn[i]*t[i]);
32     }
33     return ((ans%M)+M)%M;
34 }
35  
36 int main()
37 {
38     freopen("cao.in","r",stdin);
39     freopen("cao.out","w",stdout);
40     cin>>n;
41     for(LL i=1;i<=n;i++)
42     {
43         scanf("%d%d",&m[i],&t[i]);
44         M*=m[i];
45     }
46      
47     cout<<CRT()<<endl;
48      
49     return 0;     
50 }

end.

 

露娜养佩奇

标签:中国剩余定理   nes   它的   mil   次数   type   []   strong   代码   

原文地址:https://www.cnblogs.com/peppa/p/8506735.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!