POJ 3863坐电梯 模拟推公式

传送门:http://poj.org/problem?id=3863

m个电梯,n次按钮,m对数字,第一个数字是上多少层,第二个是下。求出选择一个电梯n次按钮最低的楼层,注意这个楼层是大于0的!题目中也说了lowest above the ground floor!

设x次上升,测下降n-x,则上升了k层 =  a*x - b*(n-x)。

这里两种做法:

1:第一种采用数学公式上的理解,单纯就是从公式思想上来看的,上面公式变形得x为自变量的公式:k = (u+d)x - dn

这里其他已知,x未知,范围是0到n,0不可取,n可取。

从公式上看,每次都是增加或者减少一个u+d,然后在k>0的情况取最小值,我们这里直接这样,x取最大值,等于n,此时k = un,然后每次减少一个u+d,则除以u+d得的是多少个u+d,直接去u+d取模,就得到在u+d线性变化下能得到的最小的k了,注意能整除时,则最后一个u+d就是最小值了

 代码:

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <math.h>
using namespace std;
typedef long long LL;
const int MAXN = 100000000;

int main() {
    int n, m;
    freopen("business.in", "r", stdin);
    freopen("business.out", "w", stdout);
    scanf("%d%d", &n, &m);
    LL res = MAXN;
    while (m--) {
        int u, d;
        scanf("%d%d", &u, &d);
        LL x = u+d;
        LL c = u*n;
        c %= x;
        c = c?c:x;
        res = min(res, c);
    }
    printf("%I64d
", res);
    return 0;
}

2.第二种就是

另上式等于0,我们可以得到当 x'= b*n/(a+b) 时为第0层
由于 x 必须为正整数,我们对 x' 向上取整,就得到可以到达的最低楼层
但是现在有一个漏洞,如果 x' 就是一个正整数,那么我们向上取整后还是x'本身
遇到这种情况此时的x'=x'+1,也就是说我们就多上一层少下一层,就能避开到达0层了

(其实可以直接int(x+1)就直接解决上面的问题了)

#include <bits/stdc++.h>
using namespace std;
int main()
{
    freopen("business.in","r",stdin);
    freopen("business.out","w",stdout);
    long long n,m;
    while( cin>>n>>m)
    {
        long long ans = 0x3f3f3f3f3f;
        while(m--)
        {
            long long a,b;
            cin>>a>>b;
            double tmp = b*n*1.0/(a+b);
            long long x = ceil(tmp);
            long long fuck = a*x-b*(n-x);
            if(fuck==0) fuck = a*(x+1)-b*(n-x-1);
            ans=min(ans,fuck);
        }
        cout<<ans<<endl;
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/zhangmingzhao/p/7256579.html