ccf-csp #201812-2 小明放学 (100分 附解析)

2019.12.14更新,坑点加一(最终答案需要用long long存储)


题目链接:http://118.190.20.162/view.page?gpid=T81

在这里插入图片描述

题目分析

  • 算是一道模拟题吧,题目的核心在于求遇到交通的时刻,交通灯处于什么样的状态,以及根据交通灯的状态得出需要等待的时间。遇到这类问题,推荐在草稿纸上画图,理清楚思路再码。
  • 我们需要明确,交通灯的状态是循环的,而循环的周期就是 ( r + y + g ) (r+y+g) ,所以求解时可以将经过的时间段对周期取模
  • 根据交通灯的变化的时间将分成区间 [ 0 , t ) , [ t , t + g ) , [ t + g , t + g + y ) , [ t + g + y , g + y + r ) [0,t),[t,t+g),[t+g,t+g+y),[t+g+y,g+y+r) ,看取余得到的时间落在哪个区间就可以知道交通灯状态了。(注意不要忽略第四个区间
    在这里插入图片描述

坑点:
题目没写明什么时候该走什么时候该等(吐槽

  1. 红灯:等到绿灯即可通行
  2. 绿灯:直接通行
  3. 黄灯:黄灯等完后还要等到红灯结束才能通行

以及最终的答案需要用long long存储(看题目数据范围的时候,就应该提前分析好用什么类型存储了

代码如下

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;
const int maxn = 1e5 + 10;
int r, y, g, n, k, t;
long long ans;
int getTime(int type, int t, int total) {
	//根据交通灯的初始状态进行分类讨论
    if (type == 1) {
        t = total - t;
        //根据最后时间段落在哪个区间进行分类讨论
        if (t < 0) return -t; //最终为红灯
        else if (t < g) return 0; //最终为绿灯
        else return t < (g + r) ? (y - (t - g)) + r : (r + g + y - t); //最终为黄灯或红灯
    } else if (type == 2) {
        t = total - t;
        if (t < 0) return r - t;
        else if (t < r) return r - t;
        else return t < (r + g) ? 0 : (r + g + y - t) + r;
    } else if (type == 3) {
        t = total - t;
        if (t < 0) return 0;
        else if (t < y) return y - t + r;
        else return t < (y + r) ? r - (t - y) : 0;
    } else {
        return t;
    }
}

int main()
{
//    freopen("1.in", "r" ,stdin);
    scanf("%d%d%d", &r, &y, &g);
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) {
        scanf("%d%d", &k, &t);
        ans += getTime(k, t, ans % (r + y + g));
    }
    printf("%lld\n", ans);
    return 0;
}

最后再附上一组帮我找到bug的数据:

input:
30 3 30
8
0 50
1 20
0 11
2 2
0 50
0 25
3 10
0 3

outpu:
173
发布了59 篇原创文章 · 获赞 103 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_42292229/article/details/102490036