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

韩信点兵-中国剩余定理(练习)

时间:2014-05-09 02:28:45      阅读:297      评论:0      收藏:0      [点我收藏+]

标签:算法   acm   编程   

http://acm.nyist.net/JudgeOnline/problem.php?pid=34提交地址

韩信点兵-中国剩余定理。

题目可以用枚举很简单的做出来,在这里写是为了运用一下刚刚学习的中国剩余定理。

以前写过中国剩余定理的博客在这就不多说了。

如果下面的字母看不懂请看我的另一篇博客http://blog.csdn.net/u010123208/article/details/24314627

说一说思路吧。

1.首先我们要用数组存储我们的要的除数,和余数。我们用m[]来存储,余数我们用a[]来存储。

2.接下来我们要计算M了 ,然后是mi mi的值我用mm[]来存储的。

3.现在主要的任我就是计算mi的逆元了。计算逆元我们当然要用扩展欧几里得定理了。注意在用扩展欧几里得定理的时候我们会遇到这样的问题,返回的结果是个负数,举个例子就是 m1的逆元  mm[1]x + m[1]y = 1;返回x=-1,y=12,这个可是这不是我们想要的数值,我们可以用m[1]+x = 2; mm[1]-y=23;(这个结论是我在群里问他们,他们说自己计算一下,具体的也没说,我就突然想到这样来计算试试,结果真行,我又试了几个,也行,这具体怎样我也不知道。希望有看到博客对扩展欧几里得定理比较清楚的给我留下言,我请教一下,在这谢谢了)。

4 我们需要的东西都已经求出来了。我们就可以计算结果了。(如果不知道请看我的另一篇博客中介绍的)

下面贴出代码,代码只是为了练习而已,对于上面的题目而言,提交肯定会错的,因为。。。但是只对于我们的中国剩余定理来时是正确的。

#include<iostream>
using namespace std;
int  exgcd(int  i,int  j,int  &ansx,int  &ansy)  //扩展欧几里得定理
{  
    int  d = i;  
    if(j==0)  
    {  
        ansx=1;  
        ansy=0;  
        return d;  
    }  
    d=exgcd(j,i%j,ansx,ansy);  
    int  temp = ansx;  
    ansx=ansy;  
    ansy=temp-(i/j)*ansy;  
    return d;  
} 
int main()
{
	int a[4];//余数
	for(int i=1;i<4;i++)
		cin>>a[i];
	int m[4]={0,3,5,7};//取模的数  质数
	int mm[4]={0,35,21,15};
	int t[4];//逆元
	for(int i=1;i<4;i++)
	{
		int x,y;
		exgcd(mm[i],m[i],x,y);
		if(x<0)
			x=m[i]+x;
		t[i]=x;
	}
	int sum=0;
	for(int i=1;i<4;i++)
	{
		sum=sum+t[i]*a[i]*mm[i];
	}
	cout<<sum%105<<endl;
	system("pause");
}
好了!

感谢自己坚持。

韩信点兵-中国剩余定理(练习),布布扣,bubuko.com

韩信点兵-中国剩余定理(练习)

标签:算法   acm   编程   

原文地址:http://blog.csdn.net/u010123208/article/details/25332135

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