ccf19年第二题小明放学,想问一下这个程序哪里错了。我自己运行样例是对的。但是提交到ccf上只有40分

w41394387 2019-03-15 11:23:47
题目背景

  汉东省政法大学附属中学所在的光明区最近实施了名为“智慧光明”的智慧城市项目。具体到交通领域,通过“智慧光明”终端,可以看到光明区所有红绿灯此时此刻的状态。小明的学校也安装了“智慧光明”终端,小明想利用这个终端给出的信息,估算自己放学回到家的时间。

问题描述

  一次放学的时候,小明已经规划好了自己回家的路线,并且能够预测经过各个路段的时间。同时,小明通过学校里安装的“智慧光明”终端,看到了出发时刻路上经过的所有红绿灯的指示状态。请帮忙计算小明此次回家所需要的时间。

输入格式

  输入的第一行包含空格分隔的三个正整数 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。



import java.util.*;
public class XiaoMingFangXue {
public static void main(String[]args) {
Scanner in=new Scanner(System.in);
int r=in.nextInt();
int y=in.nextInt();
int g=in.nextInt();
int n=in.nextInt();
int s=0,total=r+y+g;

for(int i=0;i<n;i++) {
int k=in.nextInt();
int t=in.nextInt();
int s1=s%total; //s1表示不会超过红黄绿灯都亮一次
if(k==0) {
s=s+t;
}
if(k==1) {
if(s1<t) s=t-s1+s; //小明走到这里时是红灯
else if(s1>t+g&&s1<total+t) s=total-s1+t+s;//走到这里时是黄灯或者红灯
}
if(k==2) {
if(s1<t) s=(t-s1)+r+s; //走到这里是黄灯
else if(t<s1&&s1<r+t) s=(r+t-s1)+s;//走到这里是红灯
else if(t+r+y<s1) s=total+t-s1+r+s;//走到这里是下一个黄灯

}
if(k==3) {
if(s1>t&&s1<r+y+t) //走到这里是黄灯或者红灯
s=r+y-s1+t+s;
}
}System.out.println(s);
in.close();
}
}
...全文
271 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
w41394387 2019-03-19
  • 打赏
  • 举报
回复
引用 10 楼 qybao 的回复:
else if (s1<t+g&&s1<=total+t)的s1<=total+t是不对的?s1=s%total,所以s1本身就小于total,这个比较无意义 你要知道,total是红绿黄灯走一圈的时间轮回,s%total就是走到路灯口时,路灯正好走了n个轮回后还多余出来的时间。那么如果是红灯(index=1),多出来的时间s1小于t,说明走到路灯口时红灯没变(多余出来的时间落在红灯区),所以需要等待t-s1;如果s1>t&&<=t+g,说明多余出来的时间落绿灯区,可以直接通过;如果s1>t+g&&<=t+g+y,说明多余的时间落黄灯区,理论上可以直接通过,如果题目要求黄灯也不能通过,那么黄灯开始了s1-t-g,需要等待y+r-(s1-t-g);如果s1>t+g+y,说明多余出来的时间又落到了红灯区,红灯开始了s1-t-g-y,还需等待r-(s1-t-g-y) 其他的index依此类推
嗯嗯我懂了!谢谢!
qybao 2019-03-17
  • 打赏
  • 举报
回复
else if (s1<t+g&&s1<=total+t)的s1<=total+t是不对的?s1=s%total,所以s1本身就小于total,这个比较无意义 你要知道,total是红绿黄灯走一圈的时间轮回,s%total就是走到路灯口时,路灯正好走了n个轮回后还多余出来的时间。那么如果是红灯(index=1),多出来的时间s1小于t,说明走到路灯口时红灯没变(多余出来的时间落在红灯区),所以需要等待t-s1;如果s1>t&&<=t+g,说明多余出来的时间落绿灯区,可以直接通过;如果s1>t+g&&<=t+g+y,说明多余的时间落黄灯区,理论上可以直接通过,如果题目要求黄灯也不能通过,那么黄灯开始了s1-t-g,需要等待y+r-(s1-t-g);如果s1>t+g+y,说明多余出来的时间又落到了红灯区,红灯开始了s1-t-g-y,还需等待r-(s1-t-g-y) 其他的index依此类推
w41394387 2019-03-16
  • 打赏
  • 举报
回复
import java.util.*; public class XiaoMingFangXue { public static void main(String[]args) { Scanner in=new Scanner(System.in); int r=in.nextInt(); int y=in.nextInt(); int g=in.nextInt(); int n=in.nextInt(); long s=0; long total=r+y+g; for(int i=0;i<n;i++) { int k=in.nextInt(); int t=in.nextInt(); long s1=s%total; if(k==0) { s=s+t; } if(k==1) { if(s1<=t) s=t-s1+s; //小明走到这里时是红灯 else if(s1>=t+g&&s1<=total+t) //走到这里时是黄灯或者红灯 s=total-s1+t+s; } if(k==2) { if(s1<=t) s=(t-s1)+r+s; //走到这里是黄灯 else if(t<=s1&&s1<=r+t) s=(r+t-s1)+s; //走到这里是红灯 else if(t+r+y<=s1) s=total+t-s1+r+s; //走到这里是下一个黄灯 } if(k==3) { if(s1>=t&&s1<=r+y+t) //走到这里是黄灯或者红灯 s=r+y-s1+t+s; } }System.out.println(s); in.close(); } }
qq_39936465 2019-03-15
  • 打赏
  • 举报
回复
隐藏时间边界问题,会超int需要用long
w41394387 2019-03-15
  • 打赏
  • 举报
回复
引用 6 楼 qq_39936465 的回复:
k=0 表示经过了一段道路,将会耗时 t 秒,此处 t 不超过 10^6

你肯定还有变量存在超界问题,int范围大约是2*10^9


假设如果所有路段都耗时10^6 所有灯都为红灯(红灯耗时为10^6),n=10^5,那么总耗时 10^5*10^6=10^11 超过了int 的取值范围。
这个程序的内容应该也是没错的,我对照了下面这个,还是没发现问题,感觉差不多,但是下面这个提交上去是满分,而且后来我把total也改成了long,也还是不对 import java.util.Scanner;

public class csp201812_2 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int r = input.nextInt();
int y = input.nextInt();
int g = input.nextInt();
int count = input.nextInt();
long total = r + y + g;
long result = 0;
int index;
int time;
for(int i = 0;i < count;i++){
index = input.nextInt();
time = input.nextInt();
if(index == 0){
result += time;
}
else if(index == 1){
long temp = result % total;
if(temp < time){
result += (time - temp);
}
else {
if(temp > time + g){
if(temp < time + g + y){
long tt = temp - time - g;
result += (r + y - tt);
}
else{
long tt = temp - time - g - y;
result += (r - tt);
}
}
}
}
else if(index == 2){
long temp = result % total;
if(temp < time){
result += (time - temp + r);
}
else{
if(temp < time + r){
long tt = temp - time;
result += (r - tt);
}
else if(temp > time + r + g){
long tt = temp - time - r - g;
result += (y - tt + r);
}
}
}
else{
long temp = result % total;
if(temp > time){
if(temp < time + y){
long tt = temp - time;
result += (y - tt + r);
}
else{
if(temp < time + y + r){
long tt = temp - time - y;
result += (r - tt);
}
}
}
}
}
System.out.println(result);
input.close();
}

}
---------------------
作者:丿与你丿
来源:CSDN
原文:https://blog.csdn.net/qq_38929464/article/details/86891251
版权声明:本文为博主原创文章,转载请附上博文链接!
w41394387 2019-03-15
  • 打赏
  • 举报
回复
引用 6 楼 qq_39936465 的回复:
k=0 表示经过了一段道路,将会耗时 t 秒,此处 t 不超过 10^6

你肯定还有变量存在超界问题,int范围大约是2*10^9


假设如果所有路段都耗时10^6 所有灯都为红灯(红灯耗时为10^6),n=10^5,那么总耗时 10^5*10^6=10^11 超过了int 的取值范围。
非常感谢!我懂了这个意思了,但是我看了很久,还是没发现其他超过范围的,就s和s1超过了,改成long还是不对。变量就r,g,y都不超过106,n不超过105,total也不超过105,t和k也是没超过的,都是int,那怎么还不对呢?
qq_39936465 2019-03-15
  • 打赏
  • 举报
回复
k=0 表示经过了一段道路,将会耗时 t 秒,此处 t 不超过 10^6

你肯定还有变量存在超界问题,int范围大约是2*10^9


假设如果所有路段都耗时10^6 所有灯都为红灯(红灯耗时为10^6),n=10^5,那么总耗时 10^5*10^6=10^11 超过了int 的取值范围。
qq_39936465 2019-03-15
  • 打赏
  • 举报
回复
输入的第一行包含空格分隔的三个正整数 r、y、g,表示红绿灯的设置。这三个数均不超过 10^6
qq_39936465 2019-03-15
  • 打赏
  • 举报
回复
原题是

评测用例规模与约定

  有些测试点具有特殊的性质:
  * 前 2 个测试点中不存在任何信号灯。
  测试点的输入数据规模:
  * 前 6 个测试点保证 n ≤ 10^3
  * 所有测试点保证 n ≤ 10^5
w41394387 2019-03-15
  • 打赏
  • 举报
回复
引用 1 楼 qq_39936465 的回复:
隐藏时间边界问题,会超int需要用long
我把s和s1都改成long的了,还是只有40分
w41394387 2019-03-15
  • 打赏
  • 举报
回复
引用 1 楼 qq_39936465 的回复:
隐藏时间边界问题,会超int需要用long
有点没懂诶,为什么隐藏时间边界了?为什么要用long呢

62,612

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧