csp练题记录(C语言,编译器dev c++)201812-2 小明放学
一、题目描述
二、思路分析
想法很类似上一道题,只是参数t代表的意义变了
厘清题意:k=0时,和上题情况一样(详见文后链接);k=1、2、3时,t说的是小明从家出发的时候,交通信号灯上的倒计时数字(感觉有悖生活经验,小明是有千里眼+透视吧,或者参透了先天易数之理,未卜先知吧233333)。所以遇到信号灯时,不能根据k的取值来判断它是什么灯,而是要看到这个灯时,用了多长时间,信号灯此时的变化情况。
在第一次提交代码中:我的处理方法是:
while(a>signal)//a代表到该信号灯时用了的时间(以该灯自身为原点,而不是小明的出发时刻)
a=a-signal;
这样就可以让变量a落到[0,r,r+g,r+g+y]的区间上,通过比较可得小明到达该处信号灯时,看到的灯的颜色。这种递减的算法会消耗很多时间,第一次看到运行超时的情况。。。
然后采取取模求余的思想,改写成
a=a%=signal;
就没有超时了。
还有要注意的地方时到达该灯处的时间的计算:
t是倒计时,而且是出发时该灯颜色的倒计时。所以当为红灯时,小明到该灯时,灯走了的时间为(red-t)[t是倒计时嘛]+小明用的时间。有点类似于参考系变换,小明放学用的时间是以小明离开学校为原点,而判断小明到达该灯处灯的变化情况是以灯自身为原点来看的。
三、代码
第一次提交,60分代码:
#include<stdio.h>
#include<stdlib.h>
int signal,red,yel,gre;
int sign(int a)
{
int wait;
while(a>signal)
a=a-signal;
if(a<red)//等号不可
wait=red-a;
else if(a<red+gre)
wait=0;
else
wait=signal-a+red;
return wait;
}
int main()
{
int n,k,t,time=0,temp;
scanf("%d %d %d",&red,&yel,&gre);
signal=red+yel+gre;
scanf("%d",&n);
while(n--)
{
scanf("%d %d",&k,&t);
switch(k)
{
//走过一段路程
case 0:time+=t;break;
//红灯的情况
case 1:temp=time+red-t;time=time+sign(temp);break;
//黄灯的情况
case 2:temp=time+yel-t+red+gre;time=time+sign(temp);break;
//绿灯的情况
case 3:temp=time+gre-t+red;time=time+sign(temp);break;
}
}
printf("%d",time);
system("pause");//是为了看输出,提交的时候删掉,不然貌似会判错
return 0;
}
修改后满分代码:
#include<stdio.h>
#include<stdlib.h>
int signal,red,yel,gre;
int sign(long long a)
{
int wait;
/* while(a>signal)
a=a-signal;*/
a=a%=signal;
if(a<red)//等号不可
wait=red-a;
else if(a<red+gre)
wait=0;
else
wait=signal-a+red;
return wait;
}
int main()
{
int n,k,t;
long long time=0,temp;
scanf("%d %d %d",&red,&yel,&gre);
signal=red+yel+gre;
scanf("%d",&n);
while(n--)
{
scanf("%d %d",&k,&t);
switch(k)
{
//走过一段路程
case 0:time+=t;break;
//红灯的情况
case 1:temp=time+red-t;time=time+sign(temp);break;
//黄灯的情况
case 2:temp=time+yel-t+red+gre;time=time+sign(temp);break;
//绿灯的情况
case 3:temp=time+gre-t+red;time=time+sign(temp);break;
}
}
printf("%lld",time);
system("pause");
return 0;
}
四、反思总结
第一次提交代码没考虑到取值范围和时间限制
题中说了r,g,y,t的范围是小于10^6,然后数据一多,定义一个int型的总时间time就显然不够了,表示范围不够。同样,数字大了,自作递减的时候耗时也就更多了,换用取模求余的思想真的很有用。