CCP-CSP认证考试 201812-2 小明放学 c/c++题解

CCF-CSP认证考试题解目录By东瓜lqd

题目描述:
在这里插入图片描述
我感觉这题还是有点难度的,不同于上一题,上一题的t,也就是时间是走到哪就是多少,这一道题是一开始时的状态,比如某一个红绿灯k=2,t=3,就表示刚开始是黄灯,还需要等3s,但是真正地走到这个位置,那灯的颜色和时间都有可能不一样了,所以关键就是要求出任一时刻灯的状态(颜色+还要等的时间),我自己是没有想出来的,参考了这位同学的代码,下面代码中的注释是我的理解。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <cstring>
#include <string>
#include <algorithm>
#include <vector>
#include <deque>
#include <list>
#include <utility>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <bitset>
#include <iterator>
using namespace std;

typedef long long ll;
const int inf = 0x3f3f3f3f;
const ll  INF = 0x3f3f3f3f3f3f3f3f;
const int PI = acos(-1);
const int E = exp(1);
const int MOD = 1e9+7;
const int MAX = 1e5+5;
int r,y,g;
int n;
int k,t;

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    cin >> r >> y >> g;/** 分别表示红、黄、绿灯亮的时间 */
    cin >> n;/** 表示经过的道路数+灯数 */
    ll sum = 0;/** 所经过的时间 */
    for(int i = 0; i < n; i++)
    {
        cin >> k >> t;
        if(k == 0)
        {
            /** 道路畅通,直接通过 */
            sum += t;
        }
        else
        {
            /** 开始的时候是红1/黄2/绿3 */
            ;/** 这个sum_t我觉得是比较难理解的地方,我的理解:
				  sum是当前经过的时间,r+y+g是红、黄、绿经过一圈的时间,
				  因为小明在那里走,但是红绿灯又不管你这么多,它还是按照三种颜色在这变化,
				  你经过了sum的时间,有可能走过了n个圈,n>=0,那我也不管你走了多少圈,
				  我只算当前应该的时间在哪,所以就是sum%(r+y+g) (如果实在不理解的话,还是自己慢慢悟吧)
			 */
            ll sum_t = sum % (r+y+g)
            if(k == 1)
            {
                if(sum_t < t)
                {
                    /** 还是红灯,而且时间没走完 */
                    sum += t - sum_t;
                }
                else if(sum_t >= t && sum_t - t < g)
                {
                    /** 红灯已经走完,走到了绿灯,不需要等待 */
                    ;
                }
                else if(sum_t >= t+g && sum_t -t-g < y)
                {
                    /** 红灯+绿灯已经走完,开始走黄灯(黄灯走完,后面要等一波红灯) */
                    sum += y - (sum_t-t-g) + r;
                }
                else if(sum_t >= t+g+y && sum_t -t-g-y < r)
                {
                    /** 红灯+绿灯+黄灯已经走完,然后又到了红灯中间,继续等红灯 */
                    sum += r - (sum_t-t-g-y);
                }
            }
            else if(k == 2)
            {
                if(sum_t < t)
                {
                    /** 还是黄灯,而且时间没走完 */
                    sum += t - sum_t + r;
                }
                else if(sum_t >= t && sum_t - t < r)
                {
                    /** 黄灯已经走完,走到了红灯,等待红灯走完 */
                    sum += r - (sum_t - t);
                }
                else if(sum_t >= t+r && sum_t -t-r < g)
                {
                    /** 黄灯+红灯已经走完,开始走绿灯,绿灯直接走即可 */
                    ;
                }
                else if(sum_t >= t+r+g && sum_t -t-r-g < y)
                {
                    /** 黄灯+红灯+绿灯已经走完,然后又到了黄灯中间,又要继续等一波 */
                    sum += y - (sum_t -t-r-g) + r;
                }
            }
            else if(k == 3)
            {
                if(sum_t < t)
                {
                    /** 还是绿灯,而且时间没走完,直接走就可以了*/
                    ;
                }
                else if(sum_t >= t && sum_t - t < y)
                {
                    /** 绿灯已经走完,走到了黄灯 */
                    sum += y - (sum_t - t) + r;
                }
                else if(sum_t >= t+y && sum_t -t-y < r)
                {
                    /** 绿灯+黄灯已经走完,走到了红灯的中间,等完红灯 */
                    sum += r - (sum_t -t-y);
                }
                else if(sum_t >= t+y+r && sum_t -t-y-r < y)
                {
                    /** 绿灯+黄灯+红灯已经走完,然后又到了绿灯 */
                    ;
                }
            }
        }
    }
    cout << sum << endl;

    return 0;
}

附带其他博主的代码,我还是没有太理解的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值