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();
}
}
...全文
281 11 打赏 收藏 转发到动态 举报
AI 作业
写回复
用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呢
在Windows 10或Windows 11操作系统中,用户经常会遇到共享打印机时出现的一系列误代码,这些误代码可能会阻碍打印机共享功能的正常使用。常见的误代码包括0x00000057、0x00000709和0x0000011b,这些代码通常指出了不同的题,比如权限不足、服务未运行或配置误等。除此之外,还有一些故障提示如“连接失败”或“内存不足”,这些都可能影响到打印机共享的稳定性。 要解决这些故障,首先要确保打印机已经正确地连接到网络,并且在需要共享的电脑上进行了设置。确保打印机驱动程序是最新的,并且在共享设置中没有误配置。对于权限题,需要检查网络上的用户账户是否具有足够的权限来访共享打印机。同时,也要确保打印机服务正在运行,特别是“Print Spooler”服务,因为这是打印机共享服务的核心组件。 在某些情况下,题可能与操作系统的更新有关,如升级到最新版的Windows 10或Windows 11后可能出现的兼容性题。这时,可能需要查看微软的官方支持文档来获取特定的解决方案或更新。 对于误代码0x00000057,这通常是由于没有足够的权限来访网络打印机或其共享资源,解决方法是确保网络打印机的权限设置正确,包括在组策略中设置相应的访权限。而0x00000709误可能是由于打印机驱动题或打印机端口配置误,可以尝试重新安装或更新打印机驱动来解决。至于0x0000011b误,这往往是因为打印机队列服务的题,检查并重启“Print Spooler”服务通常是解决这类题的常见手段。 至于“连接失败”或“内存不足”这类故障,通常与客户端和打印机之间的网络连接以及打印机本地资源的使用情况有关。检查网络连接,确保打印机所在的网络段没有故障或中断。同时,如果打印机的打印队列长时间得不到处理,可能会导致内存不足的情况,这时可能需要清理打印队列或增加打印机的内存配置。 为了帮助用户更快速地解决这些题,市面上出现了各种打印机共享误修复工具。这些工具往往通过预设的修复程序来自动检测和修正打印机共享中常见的题。它们可以快速检查打印机驱动、网络连接以及共享设置,并且能够提供一键修复功能,大幅减少了用户自行排查和解决题的难度。 然而,在使用这些修复工具之前,用户应确保这些工具的来源是安全可靠的,避免因使用不当的修复工具而引发其他系统安全或隐私题。用户可以到官方平台或者信誉良好的软件提供商处下载这些工具。通过细心检查打印机的共享设置,及时更新驱动程序和服务,以及合理使用修复工具,大多数共享打印机的题都可以得到有效的解决。

62,634

社区成员

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

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