POJ-1211Traffic Lights

Description

One way of achieving a smooth and economical drive to work is to `catch' every traffic light, that is have every signal change to green as you approach it. One day you notice as you come over the brow of a hill that every traffic light you can see has just changed to green and that therefore your chances of catching every signal is slight. As you wait at a red light you begin to wonder how long it will be before all the lights again show green, not necessarily all turn green, merely all show green simultaneously, even if it is only for a second. 


Write a program that will determine whether this event occurs within a reasonable time. Time is measured from the instant when they all turned green simultaneously, although the initial portion while they are all still green is excluded from the reckoning. 

Input

Input will consist of a series of scenarios. Data for each scenario will consist of a series of integers representing the cycle times of the traffic lights, possibly spread over many lines, with no line being longer than 100 characters. Each number represents the cycle time of a single signal. The cycle time is the time that traffic may move in one direction; note that the last 5 seconds of a green cycle is actually orange. Thus the number 25 means a signal that (for a particular direction) will spend 20 seconds green, 5 seconds orange and 25 seconds red. Cycle times will not be less than 10 seconds, nor more than 90 seconds. There will always be at least two signals in a scenario and never more than 100. Each scenario will be terminated by a zero (0). The file will be terminated by a line consisting of three zeroes (0 0 0).

Output

Output will consist of a series of lines, one for each scenario in the input. Each line will consist of the time in hours, minutes and seconds that it takes for all the signals to show green again after at least one of them changes to orange. Follow the format shown in the examples. Time is measured from the instant they all turn green simultaneously. If it takes more than five hours before they all show green simultaneously, the message ``Signals fail to synchronise in 5 hours'' should be written instead.

Sample Input

19 20   0
30
  25    35 0
0 0 0

Sample Output

00:00:40
00:05:00

Source

 本题利用了贪心法,不断循环,直至所有的区间都通过了(此时退出大循环,输出结果),或者是有一个区间没通过(此时进行下一轮小循环)。循环中的判定其实利用了《算法竞赛入门》中的《区间覆盖问题》中的思想(也就是贪心法),唯一的难点就在于怎样对循环进行初始化,以及何时退出循环或进行下一轮循环(我利用了两个标志,AllSynchronize和isSynchronize,AddSynchronize由小循环决定,并决定着是否退出大循环,isSynchronize有小循环中的元素决定,并决定是否退出小循环)。

#include<iostream>
#include<fstream>
#include<iomanip>
#include<cstdlib>
using namespace std;

ifstream fin("C:\\data34.in");
ofstream fout("C:\\data34.out");

int cycletime[100];
int begintime[100],endtime[100];
int beg,end;
int N;

void search()
{
	beg=begintime[0];
	end=endtime[0];
	while(1)
	{
		bool AllSynchronized=true;
		beg+=cycletime[0]*2;
		end+=cycletime[0]*2;
		for(int i=0;i<N;++i)
		{
			bool isSynchronized=false;
			while(begintime[i]<=end)
			{
				if(endtime[i]>=beg)
				{
					isSynchronized=true;
					beg>?=begintime[i];
					end<?=endtime[i];
					break;
				}
				begintime[i]+=cycletime[i]*2;
				endtime[i]+=cycletime[i]*2;
			}
			if(!isSynchronized)
			{
				AllSynchronized=false;
				break;
			}
		}
		if(AllSynchronized||beg>=18000)
			break;
	}
	if(beg>=18000)
	{
		fout<<"Signal failed to synchronize in 5 hours."<<endl;
	}
	else
	{
		int h,m,s;
		s=beg%60;
		beg/=60;
		m=beg%60;
		beg/=60;
		h=beg;
		fout<<setfill('0')<<setw(2)<<h<<":"<<setfill('0')<<setw(2)<<m<<":"<<setfill('0')<<setw(2)<<s<<endl;
	}
}

int main()
{
	N=0;
	int cnt=0;
	int time;
	while(cnt<3)
	{
		N=0;
		if(fin>>time&&time!=0)
		{
			cycletime[N++]=time;
			while(fin>>time&&time!=0)
			{
				cycletime[N++]=time;
			}
			for(int i=0;i<N;++i)
			{
				begintime[i]=0;
				endtime[i]=cycletime[i]-6;
			}
			search();
		}
		cnt++;     
	}
	system("pause");
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值