天天看點

CCF小明放學201812-2 C語言實作(100)

小明放學

試題編号: 201812-2

試題名稱: 小明放學

時間限制: 1.0s

記憶體限制: 512.0MB

問題描述:

題目背景

漢東省政法大學附屬中學所在的光明區最近實施了名為“智慧光明”的智慧城市項目。具體到交通領域,通過“智慧光明”終端,可以看到光明區所有紅綠燈此時此刻的狀态。小明的學校也安裝了“智慧光明”終端,小明想利用這個終端給出的資訊,估算自己放學回到家的時間。

問題描述

一次放學的時候,小明已經規劃好了自己回家的路線,并且能夠預測經過各個路段的時間。同時,小明通過學校裡安裝的“智慧光明”終端,看到了出發時刻路上經過的所有紅綠燈的訓示狀态。請幫忙計算小明此次回家所需要的時間。

輸入格式

輸入的第一行包含空格分隔的三個正整數 r、y、g,表示紅綠燈的設定。這三個數均不超過 106。

  輸入的第二行包含一個正整數 n,表示小明總共經過的道路段數和路過的紅綠燈數目。

  接下來的 n 行,每行包含空格分隔的兩個整數 k、t。k=0 表示經過了一段道路,将會耗時 t 秒,此處 t 不超過 106;k=1、2、3 時,分别表示出發時刻,此處的紅綠燈狀态是紅燈、黃燈、綠燈,且倒計時顯示牌上顯示的數字是 t,此處 t 分别不會超過 r、y、g。

輸出格式

輸出一個數字,表示此次小明放學回家所用的時間。

樣例輸入

30 3 30

8

0 10

1 5

0 11

2 2

0 6

0 3

3 10

0 3

樣例輸出

46

樣例說明

小明先經過第一段路,用時 10 秒。第一盞紅綠燈出發時是紅燈,還剩 5 秒;小明到達路口時,這個紅綠燈已經變為綠燈,不用等待直接通過。接下來經過第二段路,用時 11 秒。第二盞紅綠燈出發時是黃燈,還剩兩秒;小明到達路口時,這個紅綠燈已經變為紅燈,還剩 11 秒。接下來經過第三、第四段路,用時 9 秒。第三盞紅綠燈出發時是綠燈,還剩 10 秒;小明到達路口時,這個紅綠燈已經變為紅燈,還剩兩秒。接下來經過最後一段路,用時 3 秒。共計 10+11+11+9+2+3 = 46 秒。

評測用例規模與約定

有些測試點具有特殊的性質:

  * 前 2 個測試點中不存在任何信号燈。

  測試點的輸入資料規模:

  * 前 6 個測試點保證 n ≤ 103。

  * 所有測試點保證 n ≤ 105。

程式思想:時間肯定是在一直變化,可以将時間作為一個整體,在程式中不斷增加,但是紅綠黃燈走過的時間是作為一個循環,即要加一個判斷是否走過一個循環

if(rember>=k)

{

rember=rember-k*(rember/k);

}

但是在CCF中如果你這樣寫

while(rember>=k){

rember=rember-k;

}

是絕對運作逾時的,不能拿到滿分,因為當時間過大時,你的while極為耗時,此題主要考察 if,判斷之後燈的狀态就行了

#include<cstdio>
int main(){
	int a,b,c;
	
	scanf("%d%d%d",&a,&b,&c);
	int n;
	int op,m;
	long long int sum=0,rember=0;
	scanf("%d",&n);
	for(int i=0;i<n;i++){
		scanf("%d%d",&op,&m);
		if(op==0){
			sum=sum+m;
		}
		if(op==1){
			//等于1表示出發時,這裡是紅燈,而且還有m秒就變成綠燈,紅燈間隔a秒,然後綠燈間隔c秒,然後黃燈b秒循環
			rember=sum;//rember記錄總時間的變化 
			int k=a+b+c;
			if(rember>=k)
			{
				rember=rember-k*(rember/k);
				
			 } //保證在這個循環之内了
			 //經過幾輪的時間循環,實際上燈走過的時間為rember
			 if((m+c)>=rember&&rember>=m){//此時狀态為綠燈直接通過不加時間 
			 	
			 } 
			 if(rember<m){
			 	//此時狀态為紅燈,繼續等待,時間增加
				 sum=sum+m-rember; 
			 } 
			 if((m+c+b)>=rember&&rember>m+c){//此時狀态為黃燈 
			 	sum=sum+b-rember+(m+c)+a;
			 }
			 if(rember>(m+c+b)){//又跑到紅燈來了 
			 	sum=sum+a-rember+(m+c+b);//注意rember-(m+c+b)都是經過時間,也就是紅燈開始了多久,是以我們要知道要多久結束的時間也就是等待時間 
			 }
			 
		} 
		if(op==2){
			//等于2表示出發時,這裡是黃燈,而且還有m秒就變成紅燈,紅燈間隔a秒,然後綠燈間隔c秒,然後黃燈b秒循環
			rember=sum;
			int k=a+b+c;
			if(rember>=k)
			{
				rember=rember-k*(rember/k);
				
			 }  //保證在這個循環之内了
			 //經過幾輪的時間循環,實際上燈走過的時間為rember
			 if((m+a>=rember)&&rember>=m){//此時狀态為紅燈需要等待增加時間 
			 	sum=sum+a-rember+m; //a-(rember-m)這才是剩餘時間 
			 } 
			 if(rember<m){
			 	//此時狀态為黃燈,繼續等待,時間增加
				 sum=sum+m-rember+a; 
			 } 
			 if((m+a+c>=rember)&&rember>m+a){//此時狀态為綠燈 
			 	//直接不需要等待時間 
			 }
			 if(rember>(m+a+c)){//又跑到黃燈來了 ,既然到了黃燈肯定是要繼續等下一個紅燈 
			 	sum=sum+b-rember+(m+a+c)+a;
			 }
			 
		} 
		if(op==3){
			//等于3表示出發時,這裡是綠燈,而且還有m秒就變成黃燈,紅燈間隔a秒,然後綠燈間隔c秒,然後黃燈b秒循環
			rember=sum;
			int k=a+b+c;
			if(rember>=k)
			{
				rember=rember-k*(rember/k);
				
			 } //保證在這個循環之内了
			 //經過幾輪的時間循環,實際上燈走過的時間為rember
			 if((m+b>=rember)&&rember>=m){//此時狀态為黃燈需要等待增加時間 
			 	sum=sum+m+b-rember+a;
			 } 
			 if(rember<m){
			 	//此時狀态為綠燈,無需等待 
				 
			 } 
			 if((m+b+a)>=rember&&rember>m+b){//此時為紅燈,等待 
			 sum=sum+m+b+a-rember;
			 }
			 if(rember>(m+a+c)){//又跑到綠燈來了 ,無需等待 
			 
			 }
			 
		} 	
	}
	printf("%lld\n",sum); 
} 
           

繼續閱讀