洛谷 P5269 欧稳欧再次学车 题解

P5269 欧稳欧再次学车

题目背景

请自行脑补一张欧稳欧学车的图

题目描述

欧稳欧学车时经常用一辆橡树车练习。这辆橡树车共有 (N) 个挡位,欧稳欧每秒可以把挡位增加或减少 (1),初始时((0) 时刻)挡位为 $ 1$。

这辆车的转速范围是 ([L,R]),初始时转速为 $ L$。每次升挡时,转速会变成 (L);降挡时,会变成 (R)。欧稳欧在每秒也可以踩油门,让转速增加 (X),再对 (R)( ext{min})。如果转速连续 (K) 秒都 (=R),那么这辆车的发动机会停止工作,在这 (K) 秒结束的一瞬间停下(即使 (K) 秒中经历了降档操作,仍然算这种情况)。

这些操作我们认为都是在每秒开头的一瞬间进行的,其中换挡操作比踩油门操作先进行。而这一秒内这辆车前进的距离是 转速( imes)挡位。

现在给出欧稳欧练习时的操作序列,你需要求出他一共前进的距离是多少。

输入格式

第一行六个整数 (T,N,L,R,X,K)(T) 表示总时间。

接下来 (T) 行,每行两个整数 (x,y),表示这一秒的操作。

其中 (x=0) 表示升挡,(x=1) 表示降挡,(x=2) 表示挡位不变;(y=0) 表示不踩油门,(y=1) 表示踩油门。(不要问为什么没有刹车)

输出格式

一行一个整数,表示给定操作序列的前进距离。

如果欧稳欧在挡位为 (N) 时升挡,或在挡位为 (1) 时降挡,那么给定序列不合法,输出 (-1)

输入输出样例

输入 #1

5 3 1 10 5 100
0 1
0 0
2 1
2 1
1 1

输出 #1

83

输入 #2

3 1 1 1 1 2
2 0
2 1
2 0

输出 #2

2

输入 #3

1 2 3 4 5 6
1 0

输出 #3

-1

说明/提示

对于样例一:

第一秒挡位为 (2),转速为 (6)
第二秒挡位为 (3),转速为 (1)
第三秒挡位为 (3),转速为 (6)
第四秒挡位为 (3),转速为 (10)
第五秒挡位为 (2),转速为 (10)

对于样例二,前进两秒之后发动机就停止了工作。

对于 (30\%) 的数据,没有挡位操作(即保证 (x=2));

对于另外 (30\%) 的数据,没有踩油门操作(即保证 (y=0));

对于全部数据,保证 (1le T,N,L,R,X,Kle 10^6,Lle R)

【思路】

模拟

【说在前面的话】

其实很简单的我想复杂了
所以看了很久的题目,担心写出锅
主要原因还是因为这道题是gyh大佬给我推荐的
大佬推荐的当然简单不了啦
不过没想到gyh这么体贴我这个蒟蒻
找适合我这个水平的题目来给我做
开心qwq
(为什么不开long long 只有10分,这不对)

【题目分析】

关于档位有三个操作,关于速度有两个操作
升档,降档,不动和加速,不加速
根据给出的数据来模拟就好了

【核心思路】

根据提议来模拟就好了
先判断是升档,降档还是不动
如果是升档那就让档位增加,速度变为l
如果是降档那就让档位减少,速度变为r
如果是不动那就是不用管了

在判断是加速还是不加速
加速那就用现在速度加上x之后和r取min
不加速就不用管

还有会不会抛锚这也是一个问题
只需要开一个变量储存已经在r速度上面持续了多久
如果这个时候速度是r那就变量++
不然就要变为0

【完整代码】

#include<iostream>
#include<cstdio>
#define int long long
using namespace std;

int read()
{
	int sum = 0,fg = 1;
	char c = getchar();
	while(c < '0' || c > '9')
	{
		if(c == '-')fg = -1;
		c = getchar();
	}
	while(c >= '0' && c <= '9')
	{
		sum = sum * 10 + c - '0';
		c = getchar();
	}
	return sum * fg;
}

signed main()
{
	int ans = 0;
	int t = read(),n = read(),l = read(),r = read(),x = read(),k = read();
	int dang = 1,zhuan = l;
	int last = 0;
	for(register int i = 1;i <= t;++ i)
	{
		int opt = read(),y = read();
		if(opt == 0)//升档 
		{
			if(dang == n)
			{
				cout << -1 << endl;
				return 0;
			}
			dang ++;
			zhuan = l;//先升档
			//如果不踩油门,那就只处理升档,如果踩油门那就加速 
			if(y == 1)
				zhuan = min(r,zhuan + x); 
		}
		else
		if(opt == 1)//降档 
		{
			if(dang == 1)
			{
				cout << -1 << endl;
				return 0;
			}
			dang --;
			zhuan = r;
			if(y == 1)
				zhuan = min(r,zhuan + x);
		}
		else//档位不变 
		{
			if(y == 1)
				zhuan = min(r,zhuan + x);
		}
		ans += zhuan * dang;
		if(zhuan == r)
			last ++;
		else
			last = 0;
		if(last == k)
			break;
	}
	cout << ans << endl;
	return 0;
}
/*
6 3 1 10 5 100
0 1
0 0
2 1
2 1
1 1
1 0
*/
原文地址:https://www.cnblogs.com/acioi/p/11806616.html