Mint-10717

交上去之前我自己觉得我都不对,没想到能AC,数据的话n最大为50,所以枚举4个数的最小公倍数不超时,求最大公越数方法是欧几里得法

int gcd(int a,int b){
    return b == 0 ? a : gcd(b,a % b);
}

这题真是,无语=-=。。。。

#include<cstdio>
#include<cstring>
#define MAXD 50 + 5
#define MAX_SIZE 500000 + 10
#define Inf 1 << 30
int lcm[MAXD][MAXD];
int finally[MAX_SIZE];
int coin[MAXD];
int n,m;
int gcd(int a,int b){
    return b == 0 ? a : gcd(b,a % b);
}
void Get_lcm(){
    for(int i = 0; i < n ;i++)
        for(int j = i + 1; j < n; j++){
        lcm[i][j] = coin[i] * coin[j] / gcd(coin[i],coin[j]);
        lcm[j][i] = lcm[i][j];
    }
}
int main(){

    while(scanf("%d%d",&n,&m)){
        int cnt = 0;
        if(!n && !m) break;
        for(int i = 0; i < n ;i++)
            scanf("%d",&coin[i]);/*输入第i个硬币的面值*/
        Get_lcm();
        for(int a = 0; a < n ;a ++)
            for(int b = a + 1; b < n; b++)
              for(int c = b + 1; c  < n; c++)
                for(int d = c + 1; d < n; d ++){
                finally[cnt++] =  lcm[a][b] * lcm[c][d] / gcd(lcm[a][b],lcm[c][d]);
                finally[cnt++] =  lcm[a][c] * lcm[b][d] / gcd(lcm[a][c],lcm[b][d]);
        }
        for(int cases = 0; cases < m ; cases ++){
            int minx = Inf,miny = Inf;
            int x,y,z,j,t;
            scanf("%d",&z);
            for(int i = 0; i < cnt ; i++){
             t = z / finally[i];
             if(z % finally[i] == 0){
                 x = z;
                 y = z;
                 break;
             }
             else {
                 int p = t * finally[i];
                 int q = (t + 1) * finally[i];
                 int a = z - p;
                 int b = q - z;
                 if(a < minx){
                     minx = a;
                     x = p;
                 }
                 if(b < miny){
                     miny = b;
                     y = q;
                 }
             }
             }
            printf("%d %d\n",x,y);
        }
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值