暂无链接
电梯(lift)
题目背景
打完昆特牌后你不准备参加 NOIPNOIPNOIP 模拟赛了,因为你有更重要的赛事— NOGPNOGPNOGP(National
Olympiad in Gwent in Provinces)你现在要上电梯去 NNN 楼参加 NOGPNOGPNOGP。在你从 111 楼上电梯的同
时,你发现另有一台空电梯从 111 楼同时向 NNN 楼向上。
题面描述
NNN 层楼中有 MMM 层楼 (除了 111 层、NNN 层) 被标记了,如果有电梯到达有标记的层数时会停下来 1s1s1s , 然后标记会消失。因为标记消失了,所以下面一台电梯到这一层时就不会再停了。而且如果你的电梯和旁边电梯一起到达标记的层数的话,是你的电梯停下来,而旁边电梯会继续往上,然后标记消失。在电梯里的你也可以按下一些内部的按钮使自己的电梯在某层停下 1s1s1s (除了 111 层、NNN层)。而旁边的电梯不能让自己停 1s1s1s 。
你觉得输给一台空电梯非常丢脸,现在求在你不慢于空电梯的情况下最快在什么时候达到楼顶。若你不能不慢于空电梯,输出 −1-1−1。电梯上一层楼所需时间为 1s1s1s。注意在一层楼你只能停一次。
输入数据
第一行一个 TTT 表示数据组数
接下来每行五个数 N、M、a、b、cN、M、a、b、cN、M、a、b、c
下面给出生成 MMM 层被标记的层数的方法:
f[i]表示第i个生成的被标记的层数f[i] 表示第i个生成的被标记的层数f[i]表示第i个生成的被标记的层数
f[1]=c mod (N−2)+2f[1]=c\ mod\ (N-2)+2f[1]=c mod (N−2)+2
f[i]=(f[i−1]×a+b) mod (N−2)+2f[i]=(f[i-1]\times a+b)\ mod\ (N-2)+2f[i]=(f[i−1]×a+b) mod (N−2)+2
若生成的f[i]已经被标记了,则f[i]=现在最低的没有被标记的那一层(第1层除外)若生成的 f[i] 已经被标记了,则f[i]=现在最低的没有被标记的那一层(第1层除外)若生成的f[i]已经被标记了,则f[i]=现在最低的没有被标记的那一层(第1层除外)
输出数据
对每行数据输出一行答案。
样例数据
INPUT
3
5 3 1 8 2
4 2 6 1 1
7 2 3 1 3
OUTPUT
6
4
7
样例解释
第一份数据:(下文 你 表示你的电梯,空 表示空电梯)
一共五层楼,中间三层都被按了按扭
1s 你 、空 上 2
2s 你 停,空 上 3
3s 你 上 3,空 停 3
4s 你 主动停 3,空 上 4
5s 你 上 4,空 停 4
6s 你 上 5,空 上 5
数据范围
对于 20%的数据,N≤10N≤10N≤10, M≤10M≤10M≤10
对于 60%的数据,N≤1000N≤1000N≤1000, M≤1000M≤1000M≤1000
对于 100%的数据
N≤107N≤10^7N≤107, M≤107M≤10^7M≤107, T≤10T≤10T≤10,N≥M+2N≥M+2N≥M+2,0≤a、b、c≤10000≤a、b、c≤10000≤a、b、c≤1000,N≥3N≥3N≥3,M≥1M≥1M≥1
题解
仔细想想贪心策略,你会发现答案貌似是跟按按钮的具体楼层无关的。
当mmm为偶数的时候,我们不需要做任何操作,跟着空电梯一起向上,就能每个电梯接一半乘客从而一起到楼顶;当mmm为奇数时,我们需要在最后一个按按钮的楼层之前停下,让空电梯先上去接人,从而一起到楼顶。
注意,因为第一层楼无法停下,所以二楼的乘客我们必须接,当只有二楼被按得时候我们无法与空电梯持平,所以输出−1-1−1。
代码
#include<bits/stdc++.h>
using namespace std;
int n,m,c,T;
void in(){scanf("%d%d%*d%*d%d",&n,&m,&c);}
void ac()
{
if(c%(n-2)==0&&m==1)puts("-1");
else if(m&1)printf("%d\n",n+(m>>1));
else printf("%d\n",n+(m>>1)-1);
}
int main(){for(scanf("%d",&T);T--;)in(),ac();}