UVA 10090 - Marbles (数论)

UVA 10090 - Marbles

题目链接

题意:有两种盒子,一种代价c1,能装n1个珠子,一种代价c2,能装n2个珠子,问如何正好装n个珠子,并且使得代价最少。

思路:利用扩展欧几里得算法求出n1?x+n2?y=n的一个解(x′,y′)

就可以知道x,y的通解分别为

x=x′?n/gcd(n1,n2)+n2/gcd(n1,n2)?t

y=y′?n/gac(n1,n2)?n1/gcd(n1,n2)?t

由于x > 0 && y > 0,就可以求出t的范围。

那么t越小x越小,y越大,反之亦然。

之后利用贪心,看那种盒子比例比较优,就尽量让哪种盒子多即可。

代码:

#include <stdio.h>
#include <string.h>
#include <math.h>

long long extend_gcd(long long a, long long b, long long &x, long long &y) {
    if (b == 0) {x = 1; y = 0; return a;}
    long long d = extend_gcd(b, a % b, y, x);
    y -= a / b * x;
    return d;
}

long long n, c1, c2, n1, n2;

int main() {
    while (~scanf("%lld", &n) && n) {
    scanf("%lld%lld%lld%lld", &c1, &n1, &c2, &n2);
    long long x, y;
    long long d = extend_gcd(n1, n2, x, y);
    long long downk = ceil(1.0 * -n * x / n2);
    long long upk = floor(1.0 * n * y / n1);
    if (downk > upk || n % d) {
        printf("failed\n");
        continue;
    }
    if (c1 * n2 < c2 * n1) {
        x = n * x / d + n2 / d * upk;
        y = n * y / d - n1 / d * upk;
    }
    else {
        x = n * x / d + n2 / d * downk;
        y = n * y / d - n1 / d * downk;
    }
    printf("%lld %lld\n", x, y);
    }
    return 0;
}

UVA 10090 - Marbles (数论),布布扣,bubuko.com

时间: 2024-10-05 01:07:09

UVA 10090 - Marbles (数论)的相关文章

uva 10090 - Marbles(欧几里得+通解)

题目链接:uva 10090 - Marbles 题目大意:给出n,表示有n个珠子,现在要用若干个盒子来装.有两种盒子,一种价钱c1,可以装t1个珠子,另一种价钱c2,可以装t2个珠子.要求所卖的盒子刚好装n个珠子,并且价钱最小的方案. 解题思路:用拓展欧几里得算法求出xt1+yt2=n的一对解x′和y′,这样就有通解: x=x′ngcd(t1,t2)+t2gcd(t1,t2)k y=y′ngcd(t1,t2)?t1gcd(t1,t2)k 然后根据性价比选择一种盒子的个数尽量多. #includ

UVA 10090 - Marbles 拓展欧几里得

I have some (say, n) marbles (small glass balls) and I am going to buy some boxes to store them. Theboxes are of two types:T ype 1: each box costs c1 Taka and can hold exactly n1 marblesT ype 2: each box costs c2 Taka and can hold exactly n2 marblesI

uva 10090 Marbles

Problem F Marbles Input: standard input Output: standard output I have some (say, n) marbles (small glass balls) and I am going to buy some boxes to store them. The boxes are of two types: Type 1: each box costs c1 Taka and can hold exactly n1 marble

UVA 10090 Marbles(扩展欧几里得)

Marbles Input: standard input Output: standard output I have some (say, n) marbles (small glass balls) and I am going to buy some boxes to store them. The boxes are of two types: Type 1: each box costs c1 Taka and can hold exactly n1 marbles Type 2:

uva 10127 - Ones(数论)

题目链接:uva 10127 - Ones 题目大意:给出n,问说者少要多少为1才可以整除n. 解题思路:等于是高精度取模,直到余数为0为止. #include <cstdio> #include <cstring> int main () { int n; while (scanf("%d", &n) == 1) { int ans = 1, c = 1; while (c) { c = (c * 10 + 1) % n; ans++; } print

UVA 1350 - Pinary(数论+递推)

题目链接:1350 - Pinary 题意:二进制数,不能有连续的1,给定第n个数字,输出相应的二进制数 思路:先是递推,求出由n位组成的数字中有几个满足条件 dp[i] = dp[i - 1] + dp[i - 2],考虑最后一位放0和倒1位放0的情况. 然后用一个sum[i]记录满足<=i位一共的情况 接着利用二分找到给定的n > sum[i - 1],i的最大值,这个就是所求的答案的最高位. 因为如果这位放1,那么就会一共多sum[i - 1] + 1个数,那么就还需要添加n - (su

uva 10844 - Bloques(数论+高精度)

题目链接:uva 10844 - Bloques 题目大意:给出一个n,表示有1~n这n个数,问有多少种划分子集的方法. 解题思路:递推+高精度. 1 1 2 2 3 5 5 7 10 15 15 20 27 37 52 dp[i][j]=dp[i?1][j?1]+dp[i][j?1] dp[i][0]=dp[i?1][i?1] ans[i]=dp[i][i] 需要用到高精度,并且缩进. #include <cstdio> #include <cstring> #include &

uva 1529 - Clock(数论)

题目链接:uva 1529 - Clock 题目大意:给出两个时间,问从第一个时间变成第二个时间分针会和时针重叠几次. 解题思路:两个针重叠的时间是固定的,只要处理出这些重叠的时刻,在判断说给得时间区间包含的个数即可. #include <cstdio> #include <cstring> #include <cmath> const int T = 12 * 60 * 100; const int D = 6545; int sh, sm, eh, em; int

UVA 756 - Biorhythms(数论)

756 - Biorhythms 题目链接 基本就是裸的中国剩余定理. 代码: #include <stdio.h> #include <string.h> const int M = 23 * 28 * 33; const int m[3] = {23, 28, 33}; int p[3], d; int gcd(int a, int b, int &x, int &y) { if (!b) {x = 1; y = 0; return a;} int d = gc