DIDIDI loves to take a shower(乘法逆元)

来源:互联网 发布:下载九妖软件 编辑:程序博客网 时间:2024/06/05 20:28

DIDIDI loves to take a shower
时间限制:1000ms 内存限制:65535KB
提交总数:5 通过人数:0

题目描述
DIDIDI 是爱洗澡的好孩子,每次洗完澡后,B天之内一定要再洗一次澡,否则就会go die。
澡堂子每A天关一天门。

求:在DIDIDI不go die的情况下,每A天至少要洗几次澡
输入格式
第一行一个正整数t,代表数据组数。
接下来的t行,每行两个正整数A和B

1 <= t <= 2000
2 <= A,B <= 108
输出格式
对于每组样例,输出一行这样:
Case #i: ans

Case空格#编号:(半角)空格答案
i从1开始
ans……自己看吧,要求化简
样例输入

2
7 3
7 4

样例输出

Case #1: 5/2
Case #2: 2

提示
第一组样例:
可以理解为每周日关门,那么就是:
周三,周六,周二,周五,周一,周四,周六,周二,周五,周一,周四。
相当于两周去5次。

第二组样例:
周三,周六,周三,周六
一周去2次。
一直TLE 最后问了一个大神 先贴上大神的代码

#include <iostream>#include <vector>using namespace std;long long ex_gcd(long long a,long long b,long long &x,long long &y){    if(b==0)    {        x=1;        y=0;        return a;    }    else    {        long long r=ex_gcd(b,a%b,y,x);        y-=x*(a/b);        return r;    }}vector<long long> line_mod_equ(long long a,long long b,long long n){    long long x,y;    long long d=ex_gcd(a,n,x,y);    vector<long long> ans;    ans.clear();    if(b%d==0)    {        x=((x%n)+n)%n;        ans.push_back(x*(b/d)%(n/d));        for(int i=1;i<d;i++)            ans.push_back((ans[0]+i*n/d)%n);    }    return ans;}int main(){    int t;    cin>>t;    for(int k=1;k<=t;k++)    {        long long a,b,x,y,ansa=0,ansb=0,gg;        long long tempx,tempy;        double ttt=0;        cin>>a>>b;        gg=ex_gcd(a,b,x,y);        if(gg==1)        {            vector<long long> v=line_mod_equ(a%b,b-1,b);            for(int i=0;i<v.size();i++)            {                tempx=v[i];                tempy=(a*tempx+1)/b;                if(tempy*ansb<=ansa*tempx)                {                    ansa=tempy;                    ansb=tempx;                    gg=ex_gcd(ansa,ansb,x,y);                    ansa/=gg;                    ansb/=gg;                }            }        }        else        {            ansa=a/gg;            ansb=b/gg;        }        if(ansb==1)            cout<<"Case #"<<k<<": "<<ansa<<endl;        else            cout<<"Case #"<<k<<": "<<ansa<<"/"<<ansb<<endl;    }    return 0;}

再贴上我超时的代码

#include<iostream>#include<string>#include<algorithm>#include<set>#include<queue>#include<vector>#include<math.h>#include<string.h>#include<stdio.h>using namespace std;long long gcd(long long a,long long b){    long long tt ;    if(a>b)    {        tt = a;        a = b;        b = tt;    }    while(b)    {        tt = a%b;        a = b;        b = tt;    }    return a;}int main(void){    int ncase,num=1;    cin >> ncase;    while(ncase--)    {        long long A,B,cnt=1;        scanf("%lld %lld",&A,&B);        printf("Case #%d: ",num++);        if(A%B == 0)        {            printf("%lld\n",A/B);            continue;        }        long long gd = gcd(A,B);        if(gd!=1)        {            printf("%lld/%lld\n",A/gd,B/gd);            continue;        }        long long t = A;        while(1)        {            if((A+1) % B == 0)            {                long long tt = gcd((A+1)/B,cnt);                if(cnt/tt == 1)                    printf("%lld\n",(A+1)/B/tt);                else                    printf("%lld/%lld\n",(A+1)/B/tt,cnt/tt);                break;            }            else if(A % B == 0)            {                long long tt = gcd((A)/B,cnt);                if(cnt/tt == 1)                    printf("%lld\n",(A)/B/tt);                else                    printf("%lld/%lld\n",(A)/B/tt,cnt/tt);                break;            }            A += t;            cnt++;        }    }    return 0;}
原创粉丝点击