楼
【问题背景】
zhx 为他的妹子造了一幢摩天楼。
【问题描述】
zhx 有一幢摩天楼。 摩天楼上面有 M 个观光电梯,每个观光电梯被两个整数u " ,d " 描述。每个电梯只有两个按钮, (针对第 i 个电梯)两个按钮分别可以使
电梯向上u" 层向下d" 层。摩天楼的高度是无限的,但是电梯不可以钻入地下,
也就是说是有下限的。每层楼用整数标记, 以 0 作为地面这一层的标记。
zhx 去陪他妹子了,留你一个人在摩天楼的 0 层,现在你想知道,仅可以选择 M 个电梯中的一个乘坐(不可以中途换电梯) ,按电梯中的按钮 N 次后(每次两个按钮选一个按) ,可以到达的最低楼层数。按电梯的过程中请注意,如果当前所在楼层数小于你选择的d" ,你将无法选择电梯向下运行。
【输入格式】
第一行两个数 N 和 M,如题目描述。
接下来 M 行,每行两个整数d " 和u " 。
【输出格式】
仅一行一个整数,包含所求的答案。
【样例输入】
10 3
15 4
15 12
7 12
【样例输出】
13
【数据范围与规定】
对50%的数据,所有1≤N,M≤1000。
对于100%的数据,所有1≤N≤10^7,1≤M≤2000,1≤u, d≤10^5 。
分析: 思路题,想想就想出来了 很容易想到n*m的做法,就是对于每个i枚举一个合适的j,使上升和下降的差值最小,然后我们可以把这个j算出来,省去第二维循环。 代码: #include<cstdio> #include<iostream> #define ll long long #define M 2010 #define INF 10000000000000LL using namespace std; ll up[M],down[M],n,m,ans=INF; ll read() { ll num=0,flag=1;char c=getchar(); while(c<'0'||c>'9'){if(c=='-')flag=-1;c=getchar();} while(c>='0'&&c<='9'){num=num*10+c-'0';c=getchar();} return num*flag; } int main() { //freopen("jh.in","r",stdin); freopen("building.in","r",stdin); freopen("building.out","w",stdout); n=read();m=read(); for(ll i=1;i<=m;i++) up[i]=read(),down[i]=read(); for(ll i=1;i<=m;i++) { ll uc=(down[i]*n)/(down[i]+up[i]); ll dc=n-uc; for(ll j=-1;j<=1;j++) if(uc+j>=0&&dc-j>=0&&(uc+j)*up[i]-(dc-j)*down[i]>=0) ans=min(ans,(uc+j)*up[i]-(dc-j)*down[i]); } cout<<ans; return 0; }