POJ1006 Biorhythms

题目大意:求出三个生理期的共同日

思路:

即是X%23=0(从第零天开始的)

X%28=0

X%33=0

但是又因为:

p%23=0,e%28=0,i%33=0;

所以

X=p+23*y1  (yi是整数)

X=e+28*y2

X=i+33*y3    所以X和p同余于23,X和e同余于28,X和i同余于33;

又因为23、28、33互质;

所以用处理   符合定理使用条件的线性同余方程组的  中国剩余定理;

 


AC program:

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
using namespace std;
int m[4],a[4],M;
void exgcd(int a, int b, int &d,int &x, int &y )
{
  if(b==0)
    {
      x=1;
      y=0;
      d=a;
      return ;      
    } 
    else
        {
          exgcd(b,a%b,d,x,y);
          int tmp=x;
          x=y;
          y=tmp-(a/b)*y;     
        } 
} 
int china(int r)
{
  M=1;
  int Mi,x0,y0,d,ans=0;
  for(int i=1;i<=r;i++)
     M*=m[i];
  for(int i=1;i<=r;i++)
  {
    Mi=M/m[i];
    exgcd(Mi,m[i],d,x0,y0);
    ans=(ans+Mi*x0*a[i])%M;
            
  } 
  if(ans<0)
    ans+=M;
  return ans;   
} 
int main()
{
 int cas=1;
 int  p,e,i,d;
 while(cin>>p>>e>>i>>d)
 {
  if(p==-1&&e==-1&&i==-1&&d==-1)
     break;
  a[1]=p,a[2]=e,a[3]=i;
  m[1]=23,m[2]=28,m[3]=33;
  int ans=china(3);
  while(ans<=d)//因为这个日期要是大于d的最小整数,SO
    ans+=M;
  cout<<"Case "<<cas++<<": the next triple peak occurs in "<<ans-d<<" days."<<endl;                      
 } 
//system("pause"); 
return 0;} 


 

 

你可能感兴趣的:(POJ1006 Biorhythms)