201812-2 小明放學 csp ccf計算機職業資格認證考試真題 java

一、
題目背景
  漢東省政法大學附屬中學所在的光明區最近實施了名爲“智慧光明”的智慧城市項目。具體到交通領域,通過“智慧光明”終端,可以看到光明區所有紅綠燈此時此刻的狀態。小明的學校也安裝了“智慧光明”終端,小明想利用這個終端給出的信息,估算自己放學回到家的時間。
問題描述
  一次放學的時候,小明已經規劃好了自己回家的路線,並且能夠預測經過各個路段的時間。同時,小明通過學校裏安裝的“智慧光明”終端,看到了出發時刻路上經過的所有紅綠燈的指示狀態。請幫忙計算小明此次回家所需要的時間。
輸入格式
  輸入的第一行包含空格分隔的三個正整數 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
  
 二、一些坑
 這題看起來好像不難,但卻折磨了我很久。第一次提交只得了60分,上網查了查發現都在說使用int型會溢出,需要使用long型。我一臉懵逼,不明白什麼情況下會發生溢出,明明數據規模看起來不大啊,但事實是——n最大爲105,t最大爲106,假設一種極限情況:n=105,每一行的t都等於106,k都等於0。那麼小明放學回家需要105乘106=1011。顯然1011用int是存不了的。
 
 三、代碼

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
       Scanner sc = new Scanner(System.in);
       long r = sc.nextLong(),y = sc.nextLong(),g = sc.nextLong();
       int n = sc.nextInt();
       long res=0;
       for(int i=0;i<n;i++){
    	   int k=sc.nextInt();long t=sc.nextLong();
    	   if(k == 0)//不是紅綠燈,直接走
    		   res += t;
    	   else{//碰到紅綠燈了,開始計算要在紅綠燈面前等多久
			   long time = res%(r+y+g);//
    		   if( time < t){//不需要變燈
    			   if(k == 1)//紅燈
    				   res += (t-time);
    			   if(k == 2)//黃燈
    				   res += (t-time+r);
    		   }else{//需要變燈
    			   time -= t;
    			   k--;//變成下一盞燈
    			   if(k==0)
    				   k = 3;
    			   while(time>=0){
    				   if(k == 1){
    					   if(time >= r){//變成下一盞燈
    						   time -= r;
    						   k=3;
    					   }
    					   else{
    						   res += (r-time);
    						   break;
    					   }
    				   }
    				   if(k == 2){
    					   if(time >= y){//變成下一盞燈
    						   time -= y;
    						   k=1;
    					   }
    					   else{
    						   res += (y-time+r);
    						   break;
    					   }
    				   }
    				   if(k == 3){
    					   if(time >= g){//變成下一盞燈
    						   time -= g;
    						   k=2;
    					   }
    					   else
    						   break;
    				   }
    			   }
    		   }
    	   }
    	   
       }
       System.out.println(res);

    }
    
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章