快速公交BRT

【问题描述】

       在城市里,快速公交(BRT)线路为一条直线,在其线路上有 n 个交叉路口,在每个路口都有一个交通信号灯,在红灯与绿灯之间周期性循环。

       在绿灯亮起持续 g 秒的期间,允许通行,之后变为红灯,保持 r 秒,红灯期间禁止车辆通行。如果一辆车正好在变为红灯的时候到达交叉口,它应该停车,但是如果是正好变成绿灯,车辆就可以继续行驶。

 所有的交通灯都有相同的变化时间,并且是同步的。换句话说,对于所有的交通灯来说,红灯(和绿灯)的相位是相同的,它们都在第 0 时刻开始变为绿色。 

       BRT公司已经设计好了公交车通过每个路段的时间,路段是指两个连续的交通灯之间的距离,或者是起点与第一个交通灯的距离,或者是最后一个交通灯与终点的距离,更精确地讲,BRT专家设计了 + 1 个正整数 li,时间以秒计,表示公交车从起点到终点时穿过第 i 路段的时间,l1 为从起点到第一个路口的时间, ln+1 表示从最后一个路口·到终点的时间。

       在一天内有 q 辆公交车离开起点,第 i 辆车在时刻 ti(以秒计)出发,公司管理者想知道公交车在什么时间可以到达终点。

【输入形式】

       输入的第一行为三个整数 n、g、r,分别表示交叉路口的个数,绿灯持续的时间和红灯持续的时间。

       接下来一行为 + 1 整数 li , i =1, ..., + 1,表示公交车通过第 i 个路段的时间。

       接下来的一行为单一的一个整数 q,表示一天内从起点出发的公交车数量,接下来的一行为 q 个整数,表示每辆公交车离开起点的时间。

【输出形式】

       输出为一行 q 个整数,分别表示每辆公交车到达终点的时间。

【样例输入】

1 3 2
5 2
5
1 2 3 4 5

【样例输出】

8 9 12 12 12

根据题目可知每个红绿灯变化的相位是相同的,也就是说在同一时间所有的红绿灯都是一样的颜色,因此可以等同于一个红绿灯,然后就好处理一些,然后我们可以通过一时间为坐标轴建立数组(注意我是怕越界所以数据开的比较大,所以就随便取了30000,这样是很不严谨的),1表示绿灯,0表示红灯

int n,g,r;//n红绿灯的个数  g,r红绿灯持续时间 
	cin>>n>>g>>r;
	int arr[30001]={0};
	int green_left=1;
	int green_right=green_left+g-1;
	int red_left=green_right+1;
	int red_right=red_left+r-1;
	while(red_right<=30000)
	{
		for(int i=green_left;i<=green_right;i++)
		{
			arr[i]=1;
		}
		for(int j=red_left;j<=red_right;j++)
		{
			arr[j]=0;
		}
		green_left=red_right+1;
		green_right=green_left+g-1;
		red_left=green_right+1;
		red_right=red_left+r-1;
	}

 然后后面根据这个时间段是否是绿灯(在arr数组中对应的是否是1来判断这个点是否可以通过路口),

int *use_time=new int[n+1];
	for(int i=0;i<n+1;i++)
	{
		cin>>use_time[i];
	}
	int shuliang_bus;
	cin>>shuliang_bus;
	
	int *begin_time=new int[shuliang_bus];
	for(int i=0;i<shuliang_bus;i++)
	{
		cin>>begin_time[i];
	}
	for(int i=0;i<shuliang_bus;i++)
	{
		int k=0;
		int sum_time=begin_time[i]+use_time[k];
		while(k<n)
		{
			k++;
			while(arr[sum_time+1]==0)
			{
				sum_time++;
			}
			sum_time=sum_time+use_time[k]; 	
		}
		cout<<sum_time<<" ";
	}
	delete [] use_time;
	delete [] begin_time;

下面是总的代码:

#include<iostream>
using namespace std;
int main()
{
	int n,g,r;//n红绿灯的个数  g,r红绿灯持续时间 
	cin>>n>>g>>r;
	int arr[30001]={0};
	int green_left=1;
	int green_right=green_left+g-1;
	int red_left=green_right+1;
	int red_right=red_left+r-1;
	while(red_right<=30000)
	{
		for(int i=green_left;i<=green_right;i++)
		{
			arr[i]=1;
		}
		for(int j=red_left;j<=red_right;j++)
		{
			arr[j]=0;
		}
		green_left=red_right+1;
		green_right=green_left+g-1;
		red_left=green_right+1;
		red_right=red_left+r-1;
	}
	int *use_time=new int[n+1];
	for(int i=0;i<n+1;i++)
	{
		cin>>use_time[i];
	}
	int shuliang_bus;
	cin>>shuliang_bus;
	
	int *begin_time=new int[shuliang_bus];
	for(int i=0;i<shuliang_bus;i++)
	{
		cin>>begin_time[i];
	}
	for(int i=0;i<shuliang_bus;i++)
	{
		int k=0;
		int sum_time=begin_time[i]+use_time[k];
		while(k<n)
		{
			k++;
			while(arr[sum_time+1]==0)
			{
				sum_time++;
			}
			sum_time=sum_time+use_time[k]; 	
		}
		cout<<sum_time<<" ";
	}
	delete [] use_time;
	delete [] begin_time;
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值