POJ1006:Biorhythms (暴力/CRT)

题目传送门:http://poj.org/problem?id=1006


题目大意:给出四个数a,b,c,d,要你求一个大于d的最小数字ans使得 ansa(mod23),ansb(mod28),ansc(mod33) a n s ≡ a ( mod 23 ) , a n s ≡ b ( mod 28 ) , a n s ≡ c ( mod 33 )


题目分析:很早就听说这是道CRT的经典例题。真正看了之后感觉暴力也能过,结果写了一发真能过……时间复杂度同样是 O(1) O ( 1 ) ,只不过有个21252的常数而已QAQ。

然而CRT可以做得更好。直接扔进CRT的式子,跑个Exgcd算一下,就可以知道答案是将a乘以5544加b乘以14421加c乘以1288模21252。注意答案要大于d。


CODE(暴力):

#include<iostream>
#include<string>
#include<cstring>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<stdio.h>
#include<algorithm>
using namespace std;

int t=0;
int a,b,c,d;

int main()
{
    freopen("1006.in","r",stdin);
    freopen("1006.out","w",stdout);

    scanf("%d%d%d%d",&a,&b,&c,&d);
    while (a!=-1)
    {
        a%=23;
        b%=28;
        c%=33;
        t++;

        int ans=d+1;
        while ( ans%23!=a || ans%28!=b || ans%33!=c ) ans++;
        printf("Case %d: the next triple peak occurs in %d days.\n",t,ans-d);

        scanf("%d%d%d%d",&a,&b,&c,&d);
    }

    return 0;
}

CODE(CRT):

//#include<iostream>
//#include<string>
//#include<cstring>
//#include<cmath>
#include<cstdio>
//#include<cstdlib>
//#include<stdio.h>
//#include<algorithm>
using namespace std;

int t=0;
int a,b,c,d;
int ans;

//int X,Y;
//int p,q,r;

/*void Exgcd(int u,int v)
{
    if (!v) X=1,Y=0;
    else
    {
        Exgcd(v,u%v);
        int x=X;
        int y=Y;
        X=y;
        Y=x-u/v*y;
    }
}*/

int main()
{
    freopen("1006.in","r",stdin);
    freopen("1006.out","w",stdout);

    /*Exgcd(23,28*33%23);
    while (Y<0) Y+=23;
    p=28*33*Y;
    Exgcd(28,23*33%28);
    while (Y<0) Y+=28;
    q=23*33*Y;
    Exgcd(33,23*28%33);
    while (Y<0) Y+=33;
    r=23*28*Y;*/

    scanf("%d%d%d%d",&a,&b,&c,&d);
    while (a!=-1)
    {
        //a%=23;
        //b%=28;
        //c%=33;
        ++t;

        ans=(a*5544+b*14421+c*1288)%21252;
        if (ans<=d) ans+=21252;

        printf("Case %d: the next triple peak occurs in %d days.\n",t,ans-d);
        scanf("%d%d%d%d",&a,&b,&c,&d);
    }

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值