UVA10717 - Mint(欧几里德求最小共倍数)

题目链接

题目大意:要求你设计桌子,桌子的四条腿是用四种不同的硬币堆砌起来,并且这四条腿的长度要求要种相同。现在给n种硬币,然后给你t个要求的高度H。要求你给出能够用这些硬币设计出来的桌子的高度最接近H的两个数。

解题思路:要求四条腿一样长的话就是求这四种硬币厚度的最小共倍数,然后这里会给n种硬币,需要枚举出每四个的组合,求出用这些硬币可以设计多高的桌子。最后再根据题目要求的高度将这些可以得到的桌子高度进行安放。

代码:

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>

using namespace std;

typedef long long ll;
const int maxn = 50;
const ll INF = 0x3f3f3f3f;

int k, t;
ll num[maxn], H[maxn];
ll L[maxn], R[maxn];

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

void init () {

    for (int i = 0; i < k; i++)
        scanf ("%lld", &num[i]);
    for (int i = 0; i < t; i++)
        scanf ("%lld", &H[i]);

    for (int i = 0; i < t; i++) {
        L[i] = 0;
        R[i] = INF;
    }
}

void solve (ll a) {

    ll tmp;
    for (int i = 0; i < t; i++) {

        tmp = a;
        while (1) {

            if (tmp == H[i]) {
                L[i] = max(L[i], tmp);
                R[i] = min(R[i], tmp);
                break;
            } else if (tmp < H[i]) {

                L[i] = max(L[i], tmp);
            } else {

                L[i] = max(L[i], tmp - a);
                R[i] = min(R[i], tmp);
                break;
            }
            tmp += a;
        }
    }
}

int main () {

    while (scanf ("%d%d", &k, &t) && (k || t)) {    

        init();
        ll tmp1, tmp2, tmp;

        for (int i = 0; i < k; i++)
            for (int j = i + 1; j < k; j++) {

                tmp1 = num[i] / gcd(num[i], num[j]) * num[j];//先除再乘防止溢出
                for (int m = j + 1; m < k; m++)
                    for (int n = m + 1; n < k; n++) {

                        tmp2 = num[m] / gcd(num[m], num[n]) * num[n];
                        tmp = tmp1 / gcd(tmp1, tmp2) * tmp2;
                        solve(tmp);
                    }
        }

        for (int i = 0; i < t; i++)
            printf ("%lld %lld\n", L[i], R[i]);
    }
    return 0;
}
时间: 2024-10-07 07:03:40

UVA10717 - Mint(欧几里德求最小共倍数)的相关文章

One Person Game(扩展欧几里德求最小步数)

One Person Game Time Limit: 2 Seconds      Memory Limit: 65536 KB There is an interesting and simple one person game. Suppose there is a number axis under your feet. You are at point A at first and your aim is point B. There are 6 kinds of operations

求最小公公倍数的三种方法

1.常规法 #include<stdio.h> #include<stdlib.h> int main(){ int a, b, i,j; printf("请输入两个数\n"); scanf("%d%d", &a, &b); for (i = 2;i<=a;i++){ if (a%i == 0 && b%i == 0) { j = i; } } printf("最大公约数为:%d",

POJ1061-青蛙的约会---扩展欧几里德算法求最小整数解

扩展欧几里得算法模板 #include <cstdio> #include <cstring> #define ll long long using namespace std; ll extend_gcd(ll a, ll b, ll &x, ll &y) { if(b == 0) { x = 1, y = 0; return a; } else { ll r = extend_gcd(b, a%b, y, x); y -= x*(a/b); return r;

HDU 3035 War(对偶图求最小割)

HDU 3035 War 题目链接 题意:根据图那样,给定一个网络,要求阻断s到t,需要炸边的最小代价 思路:显然的最小割,但是也显然的直接建图强行网络流会超时,这题要利用平面图求最小割的方法,把每一块当成一个点,共有边连边,然后每一个路径就是一个割,然后最短路就是最小割了 代码: #include <cstdio> #include <cstring> #include <vector> #include <queue> using namespace s

Knight&#39;s Trip---hdu3766(马走日求最小走的步数)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3766 给你一个x ,y 求出从(0,0)位置到达需要的最小步数每次只能走日型: 下图为暴力bfs得到的答案:可以看一下: /** 首先,xy的大小排序和转化为都是正数步数不变应该懂吧. y=2*x这种情况直接就是(x+y)/3步. 如果y<2*x但是(x+y)%3==0的话,那么我们可以通过控制(1,2),(2,1) 两种跳法的次数达到...总数必然是(x+y)/3,然后xy的和对3取余是1的话,

扩展欧几里得求最小非负整数解 (POJ 1061 青蛙约会为例)

Description 两只青蛙在网上相识了,它们聊得很开心,于是觉得很有必要见一面.它们很高兴地发现它们住在同一条纬度线上,于是它们约定各自朝西跳,直到碰面为止.可是它们出发之前忘记了一件很重要的事情,既没有问清楚对方的特征,也没有约定见面的具体位置.不过青蛙们都是很乐观的,它们觉得只要一直朝着某个方向跳下去,总能碰到对方的.但是除非这两只青蛙在同一时间跳到同一点上,不然是永远都不可能碰面的.为了帮助这两只乐观的青蛙,你被要求写一个程序来判断这两只青蛙是否能够碰面,会在什么时候碰面. 我们把这

hdu 3746 Cyclic Nacklace (KMP求最小循环节)

//len-next[len]为最小循环节的长度 # include <stdio.h> # include <algorithm> # include <string.h> using namespace std; int len; char a[100010]; int next[100010]; void Getnext() { int i=0,j=-1; next[0]=-1; while(i<=len) { if(j==-1||a[i]==a[j]) i

LeetCode -- Triangle 路径求最小和( 动态规划问题)

人们常说"细节决定成败". 编码工作中,同样需要关注细节. 本文将给出3个小实例来说明编码中关注细节的重要性,同时给出作者对如何注意编码细节的一点见解(说的不对,请指正). 例1 这个问题如此地显而易见,竟然没有被发现. List<int> numList = new List<int>(); numList.Add(3); numList.Add(1); numList.Add(4); numList.Add(2); numList.Add(5); numLi

hiho 第116周,最大流最小割定理,求最小割集S,T

#include <bits/stdc++.h> using namespace std; #define maxn 505 #define INF 0x3f3f3f3f struct Edge { int from,to,cap,flow; }; struct Dinic { int n,m,s,t; vector<Edge> edge; vector<int> G[maxn]; bool vis[maxn]; int d[maxn]; int cur[maxn];