java CSP测试里小明放学问题
首先让我们来看看问题:
题目说小明放学的时候能够在教室里看到回家路上的红绿灯状况和剩余倒计时时间,看完之后就回家了,要根据输入的红灯、绿灯、黄灯倒计时时间(样例是30、3、30),n(样例是8),以及后面n行的走一段路的时间和在教室看到的红绿灯状况来计算小明回家的时间。
首先我们要知道红绿灯是怎么跳的?(请看我另一篇的小明上学问题)
以样例为例:30,3,30分别为红灯倒计时30秒,黄灯倒计时3秒,绿灯倒计时30秒。注意,红灯以后是绿灯,绿灯以后是黄灯,即红-绿-黄循环切换,顺序不能弄错!
解题核心
有两种情况,如图:
sum为从教室出发后行走所用的实际总时间,t为小明还没从教室出发时在教室屏幕看到的某红绿灯的倒计时时,k是红绿灯的状态。
情况1:sum<=t。也就是说倒计时还没倒完,就走到了该红绿灯下。如:教室看到红灯倒计时还有28秒,从教室出来走路用了20秒。
(1)若k是绿灯,直接过。sum=sum.
(2)若k是红灯,红灯之后是绿灯。sum=看到的红灯倒计时.
(3)若k是黄灯,黄灯后是红灯,红灯后才是绿灯。
sum=看到的黄灯倒计时+规定的红灯倒计时
情况2:sum>t。也就是说倒计时倒完,还没走到了该红绿灯下。如:教室看到绿灯倒计时还有2秒,从教室出来走路用了28秒,那么就需要计算这26秒(sum-t=26)内灯从绿灯变成什么状态了。
(1)若k变成是绿灯,直接过。sum=sum.
(2)若k变成红灯,红灯之后是绿灯。sum=看到的红灯倒计时.
(3)若k变成黄灯,黄灯后是红灯,红灯后才是绿灯。
sum=看到的黄灯倒计时+规定的红灯倒计时
怎么计算sum-t这段时间内,灯变成了什么呢?
我的想法,红绿黄变换的周期是r+y+g,通过计算最后t所落在的区间来进行判断k变成了什么灯,落在【0,r)是红灯,【r,r+g)是绿灯,【r+g,r+g+y)是黄灯。
如,样例:
30,3,30,
8
0,10
1,5
【0,30)是红灯,【30,60)是绿灯,【60,63)是黄灯。
sum为10>t为5,因为k为1是红灯,30-5=25(将5秒的倒计时变成红灯范围的时刻) ,25+10=35(sum为10,35落在绿灯范围,根据情况2的(1)可直接通过,sum不变)
为使计算的t在【0,r+y+g】需要求余。
综上,情况2计算sum-t时间内灯变化的情况是:
k为1,计算落在红灯(r-t+sum)%(r+y+g)
k为2,计算落在黄灯(r+y+g-t+sum)%(r+y+g)
k为3,计算落在绿灯(r+g-t+sum)%(r+y+g)
然后根据情况2的(1)(2)(3)计算总时间。
代码如下:
import java.util.Scanner;
class CountTime{
int r,y,g=0;
int sum=0;
void countNumber(int[] One,int[][] Two) {
for(int i=0;i<One[3];i++) {
if(Two[i][0]==0) {
sum+=Two[i][1];//走一段路的时间
}else {
sum=comper(Two[i][0],Two[i][1]);
}
}
System.out.println(sum);
}
int comper(int k,int t) {
int tep=0;
if(sum<=t) { //在教室看到的倒计时大于目前行走的总时间
switch(k) {
case 1: tep=t;break;//红灯
case 2: tep=t+r;break;//黄灯
case 3: tep=sum;break; //绿灯
}
}else {//在教室看到的倒计时小于目前行走的总时间
switch(k) {
case 1: tep=(r-t+sum)%(r+y+g);break;//r-t为教室看到的红灯区的时刻,如红灯是30,
case 2: tep=(r+y+g-t+sum)%(r+y+g);break;//红灯倒计时t为6则为24,加上sum后为目前所在的灯的时刻,取余后将范围限定在r+y+g
case 3: tep=(r+g-t+sum)%(r+y+g);break;
}
if(tep>=0&&tep<r) {//落在红灯区,总时间+等红灯区倒计时时间
tep=sum+(r-tep);
}else if(tep>=r&&tep<=(r+g)){//落在绿灯区,直接过不用等
tep=sum;
}
else {
tep=sum+(r+y+g-tep)+r;//落在黄灯区,总时间+等黄灯区倒计时时间+等红灯区倒计时时间
}
}
return tep; //返回tep,tep为总时间
}
CountTime(int[] One){ //初始化r y g
r=One[0];
y=One[1];
g=One[2];
}
}
public class OutSchool {
public static void main(String[] args) {
Scanner scan=new Scanner(System.in);
int[] arryOne=new int[4];//存储r,y,g,n的值
for(int i=0;i<arryOne.length;i++) {
arryOne[i]=scan.nextInt();
}
int[][] arryTwo=new int[arryOne[3]][2];//存储n行2列的k,t值
for(int i=0;i<arryOne[3];i++) {
for(int j=0;j<2;j++) {
arryTwo[i][j]=scan.nextInt();
}
}
scan.close();
CountTime count=new CountTime(arryOne);
count.countNumber(arryOne,arryTwo);
}
}
输入输出格式没细写,结果没问题。
不足之处多多指教。