洛谷 P5269 歐穩歐再次學車 題解

P5269 歐穩歐再次學車

題目背景

請自行腦補一張歐穩歐學車的圖ios

題目描述

歐穩歐學車時常常用一輛橡樹車練習。這輛橡樹車共有 \(N\) 個擋位,歐穩歐每秒能夠把擋位增長或減小 \(1\),初始時(\(0\) 時刻)擋位爲 $ 1$。spa

這輛車的轉速範圍是 \([L,R]\),初始時轉速爲 $ L$。每次升擋時,轉速會變成 \(L\);降擋時,會變成 \(R\)。歐穩歐在每秒也能夠踩油門,讓轉速增長 \(X\),再對 \(R\)\(\text{min}\)。若是轉速連續 \(K\) 秒都 \(=R\),那麼這輛車的發動機會中止工做,在這 \(K\) 秒結束的一瞬間停下(即便 \(K\) 秒中經歷了降檔操做,仍然算這種狀況)。code

這些操做咱們認爲都是在每秒開頭的一瞬間進行的,其中換擋操做比踩油門操做先進行。而這一秒內這輛車前進的距離是 轉速\(\times\)擋位。get

如今給出歐穩歐練習時的操做序列,你須要求出他一共前進的距離是多少。io

輸入格式

第一行六個整數 \(T,N,L,R,X,K\)\(T\) 表示總時間。ast

接下來 \(T\) 行,每行兩個整數 \(x,y\),表示這一秒的操做。class

其中 \(x=0\) 表示升擋,\(x=1\) 表示降擋,\(x=2\) 表示擋位不變;\(y=0\) 表示不踩油門,\(y=1\) 表示踩油門。(不要問爲何沒有剎車)stream

輸出格式

一行一個整數,表示給定操做序列的前進距離。變量

若是歐穩歐在擋位爲 \(N\) 時升擋,或在擋位爲 \(1\) 時降擋,那麼給定序列不合法,輸出 \(-1\)im

輸入輸出樣例

輸入 #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\));

對於所有數據,保證 \(1\le T,N,L,R,X,K\le 10^6,L\le 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
*/
相關文章
相關標籤/搜索