HDU 1573 X问题
该题是一道中国剩余定理题目,刚开始我就用了一下暴力的方法 (同时也优化了一下)一下子就超时了,后来看了一下这个题的解题报告才知道要用中国剩余定理,这也是我第一次用中国剩余定理解题。
这个定理又叫孙子定理。
就是给定几个数 虽然不互质 然后一个数取余他们又有相应的余数。那么这个问题的答案相差的一定是这些数的最小公倍数。
首先我们求出最小公倍数K;
然后在N%k+1到N%k+k这个范围内暴找一下有没有一个符合所有条件的数,我们把N分成一段段的,因为在每一段一定是没有或者只有一个的。为什么可以分成一段段的,我们知道中国剩余定理求的是最小的数,那么它的倍数同样是符合条件的;
所以如果有的话 sum+=n/k;
不要忘记,然后判断在1到n%k这个范围内有没有符合条件的答案 ( 因为我们是从数的最后面分段开始的,最前面可能还有数剩余 )。
#include<stdio.h>
#include<stdlib.h>
int Gcd( int a, int b )
{
b==0?a:Gcd( b, a%b );
}
int judge( int a[], int b[], int n, int sum, int N )
{
int count=0;
int t=N%sum;
for( int i=t+1;i<=sum+t;i++ )
{
int cnt=0;
for( int j=0; j<n; j++ )
{
if( i%a[j]==b[j] )
cnt++;
else break;
}
if( cnt==n )
{
count+=N/sum;
break;
}
}
for( int i=1;i<=t; i++ )
{
int cnt=0;
for( int j=0; j<n; j++ )
{
if( i%a[j]==b[j] )
cnt++;
else break;
}
if( cnt==n )
{
count++;
break;
}
}
return count;
}
int main( )
{
int a[10],b[10];
int n,T,N;
scanf( "%d",&T );
while( T-- )
{
int sum=1;
scanf( "%d%d",&N, &n );
for( int i=0; i<n; i++ )
{
scanf( "%d",&a[i] );
int t=Gcd( sum , a[ i ] );
sum*=(a[i]/t);
}
for( int i=0; i<n; i++ )
scanf( "%d",&b[i] );
printf( "%d\n",judge( a,b,n,sum,N ) );
}
return 0;
}