hdu 1573(中国剩余定理非互质情况)

解题思路:这道题目有可能a[i],两两不互质,所以直接用中国剩余定理肯定是不对的。。这里考虑非互质的情况

ee09991f-0311-31c0-986f-a838796b7646.png (141×100)

问题描述:给出bi,ni的值,且n1, n2, n3,…, ni两两之间不一定互质,求Res的值? 
解:采用的是合并方程的做法。 
这里将以合并第一第二个方程为例进行说明
 
由上图前2个方程得(设k1、k2为某一整数):
 

5e55e37f-5abf-376a-bc59-41f9f93651a2.jpg (562×479)

2ff1e981-2405-31ff-87b4-13c2d3715c03.png (501×484)

这里实际上是利用了一种迭代的思想,前两个方程合并成一个新的模方程,然后再与第三个合并.......,一直到最后一个方程,最后可以求出解来。。注意这里为了求出最小非负整数解,采用了很多技巧。。


#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

int gcd(int a,int b,int &x,int &y)
{
	if(a == 0 && b == 0) return -1;
	if(b == 0)
	{
		x = 1;
		y = 0;
		return a;
	}
	int d = gcd(b,a%b,y,x);
	y -= a/b*x;
	return d;
}

int main()
{
	int n,m,t,m1,m2,r1,r2,flag;
	int a[11],b[11];
	cin>>t;
	while(t--)
	{
		cin>>n>>m;
		for(int i = 0; i < m; i++)
			cin>>a[i];
		for(int i = 0; i < m; i++)
			cin>>b[i];
		flag = 0; m1 = a[0]; r1 = b[0];
		for(int i = 1; i < m; i++)
		{
			int x,y;
			m2 = a[i]; r2 = b[i];
			int d = gcd(m1,m2,x,y);
			int c = r2-r1;
			if(c % d)
			{
				flag = 1;
				break;
			}
			int tmp = m2 / d;
			x = (c / d * x % tmp + tmp) % tmp;
			r1 = r1 + x * m1;
			m1 = m1 / d * m2;
		}
		if(flag || n < r1) 
			cout<<0<<endl;
		else
		{
			int ans = (n - r1) / m1 + 1;  //m1为ai的最小公倍数,凡是m1*i+r1的都是符合要求的数,其中r1最小  
			if(r1 == 0) ans--;        //要求是正整数  
			cout<<ans<<endl;
		}
	}
	return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值