CCF 201812-2 小明放学 C++

在这里插入图片描述
在这里插入图片描述
分析:

60分是因为用int会有溢出,
所以反正是为了AC,那么以后看到数据点超过10^5都可以直接用长长整型
还有对于只需要处理下一状态的数据的情况,可以考虑不使用数据结构存储输入的数据,直接在输入的时候就进行处理。
网上的答案我没能理解它的逻辑,所以还是按自己能搞清楚的逻辑写的。

remain_time是当前信号灯的剩余时间 减去 已经走过的时长。
大于0表示还在当前信号灯状态;
不大于0的时候,需要通过取模操作获取,此时remain_time是从当前信号灯的下一个状态的0时刻起
all_round = r + y + g

其实这一题,就是要看当前信号灯时长在经历sum_time后,到绿灯还要多久的时间

  1. 如果当前是红灯,时间区间就是绿 黄 红 [0, g) [g, g+y) [g+y, all_round)
    那么只需要用 all_round - remain_time

  2. 如果当前是黄灯,时间区间就是红 绿 黄 [0, r) [r, r+g) [r+g, all_round)
    那么到绿灯 分两种情况
    转换后为红灯 那么就是 r - remain_time
    转换后为黄灯 则 all_round - remain_time + r

  3. 如果当前是绿灯,时间区间 黄 红 绿 [0, y) [y, y+r) [y+r, all_round)
    那么就是 y+r - remain_time

#include <bits/stdc++.h>
using namespace std;

void Handle();
typedef long long int ll;

int main() {
	Handle();
	return 0;
}

void Handle() {
	ll r, y, g;
	cin >> r >> y >> g;
	ll all_round = r + y + g;
	int n;
	cin >> n;
	
	int k;
	ll t;
	ll sum_time = 0;
	ll remain_time = 0;

	for (int i = 0; i < n; i++)
	{
		cin >> k >> t;

		switch (k)
		{
		case 0:
			sum_time += t;
			break;
		case 1: //红灯
			remain_time = t - sum_time;
			if (remain_time <= 0) //需要进行红绿灯状态转换
			{
				remain_time = abs(remain_time) % all_round;
				if (remain_time >= g && remain_time < all_round)
					sum_time += all_round - remain_time;
			}
			else
				sum_time += remain_time;
			break;
		case 2: //黄灯
			remain_time = t - sum_time;
			if (remain_time <= 0)
			{
				remain_time = abs(remain_time) % all_round;
				if (remain_time >= 0 && remain_time < r) //转换后为红灯
					sum_time += r - remain_time;
				else if (remain_time >= r+g && remain_time < all_round) //转换后为黄灯
					sum_time += all_round - remain_time + r;
			}
			else
				sum_time += remain_time + r;
			break;
		case 3: //绿灯
			remain_time = t - sum_time;
			if (remain_time <= 0)
			{
				remain_time = abs(remain_time) % all_round;
				if (remain_time >= 0 && remain_time < y + r)  //转换后为红灯或黄灯
					sum_time += y + r - remain_time;
			}
			break;
		default:
			break;
		}
	}

	cout << sum_time;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值