hdu 1573 X问题

X问题

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3305    Accepted Submission(s): 1071


Problem Description
求在小于等于N的正整数中有多少个X满足:X mod a[0] = b[0], X mod a[1] = b[1], X mod a[2] = b[2], …, X mod a[i] = b[i], … (0 < a[i] <= 10)。
 

Input
输入数据的第一行为一个正整数T,表示有T组测试数据。每组测试数据的第一行为两个正整数N,M (0 < N <= 1000,000,000 , 0 < M <= 10),表示X小于等于N,数组a和b中各有M个元素。接下来两行,每行各有M个正整数,分别为a和b中的元素。
 

Output
对应每一组输入,在独立一行中输出一个正整数,表示满足条件的X的个数。
 

Sample Input
  
  
3 10 3 1 2 3 0 1 2 100 7 3 4 5 6 7 8 9 1 2 3 4 5 6 7 10000 10 1 2 3 4 5 6 7 8 9 10 0 1 2 3 4 5 6 7 8 9
 

Sample Output
  
  
1 0 3
 

自己思路贴的代码(TLM):

#include<stdio.h>
#include<iostream>
using namespace std;
int a[10],b[10];

int main ()
{
 int T,n,m;
 int i,j,flag;
 cin>>T;
 while(T--)
 {
  cin>>n>>m;
  for(i=0;i<m;i++)
	  cin>>a[i];
  for(i=0;i<m;i++)
	  cin>>b[i];
  int sum=0;
  for(i=1;i<=n;i++)
  {
    flag=1;
	for(j=0;j<m;j++)
	{
		if(i%a[j]!=b[j])
		{
			flag=0;
			break;
		}
	}
	if(flag) 
		sum++;
	else 
		continue;
  }
  cout<<sum<<endl;
 }
 return 0;
}


中国剩余定理:


//中国剩余定理的普通情况:ai不一定相互互质 

#include <cstdio>  
#include <cstring>  
#include <iostream>  
using namespace std;  
int gcd(int a,int b,int &x,int &y)  
{
	
    int d,temp;
	if(b==0)   //a*x+b*y=gcd(a,b)=d;(x0,y0)为其一组整数解
	{
		x=1;
		y=0;
		return a;
	}  
    d = gcd(b,a%b,x,y); 
	temp = x;
	x = y; 
	y = temp - a/b * y;
	return d; 
}  

int main()  
{  
	int n,m,m1,r1,m2,r2,flag=0;
	int a[11],b[11],T;  
	cin>>T;  
	while(T--)  
	{     
		int i,j;
		int x,y,d,c,t;
		
		cin>>n>>m;  
        for(i=0;i<m;i++)  
			cin>>a[i];  
        for(i=0;i<m;i++)  
			cin>>b[i]; 
		
		flag=0;  
		m1=a[0];r1=b[0];  
		for(i=1;i<m;i++)  
		{  
			m2=a[i];r2=b[i];  
			if(flag)
				continue;  
			d=gcd(m1,m2,x,y);   //x*m1+y*m2=gcd(m1,m2);  
			c=r2-r1;  
			if(c%d)          //对于方程m1*x+m2*y=c=r2-r1,如果c不是d的倍数就无整数解  
			{  
				flag=1;  
				continue;  
			}
			//对于方程m1x+m2y=c=r2-r1,若(x1,y1)是一组整数解,那么(x1+k*m2/d,y1-k*m1/d)也是一组整数解(k为任意整数)  
			//其中x1=x0*c/d,y1=x0*c/d; (x0,y0为方程a*x+b*y=gcd(a,b)=d的一组整数解)
			t=m2/d;  
			x=(c/d*x%t+t)%t;    //保证x0是正数,因为x+k*t是解,(x%t+t)%t也必定是正数解(必定存在某个k使得(x%t+t)%t=x+k*t)  
			
			r1=m1*x+r1;
            m1=m1*m2/d;  
		}  
		
		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
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值