CSP 201812-2 小明放学

CSP 201812-2 小明放学

在这里插入图片描述
样例可过,20分

#include<stdio.h>
#include<algorithm>
#include<math.h>
using namespace std;

int main(void){
    int r,y,g,n,num=0,type,t,in;
    scanf("%d%d%d",&r,&y,&g);
    scanf("%d",&n);
    for(int i=0;i<n;i++){
        scanf("%d%d",&type,&t);
        in=num%(r+g+y);
        if(type==1){
            if(in>=t&&in-t<=30){}
            if(in-t>=30)num+=r+y+t;
            if(in<t)num=num+t-in;
        }
        else if(type==2){
            if(in>=t+r&&in-t-r<=30){}
            if(in<t+r)num+=abs(in-t-r);
            if(in-t-r>30)num=num+r+y+t+r;
        }
        else if(type==3){
            if(in<=t){}
            if(in>t&&in-t<=33)num=num+abs(in-r-y-t);
            if(in-t>33)num=num+r+y;
        }
        else num+=t;
    }
    printf("%d",num);
}

/*
30 3 30
8
0 10
1 5
0 11
2 2
0 6
0 3a
3 10
0 3
*/

室友100分代码+讲解
我们知道,红绿灯的颜色变换是有规律的,可以看成按红灯(r)、绿灯(g)、黄灯(y)的顺序交替变换的(看成按g, y, r的顺序是一样的;要注意的是黄灯接在绿灯后面,红灯在黄灯后面)。一次变换周期的耗时p有:p = r + g + y。依据这一规律,我们能够求出:小明到达某个路口时,该路口的红绿灯状态。这一个问题可以分解为4个子问题。
(1)假设出发时,路口的红绿灯状态是红灯剩余rr秒,经过T秒后,该路口的红绿灯处于变换周期的第几秒?从开始亮红灯算起,红绿灯周期已经经过了r - rr秒,经过T秒后,处于变换周期中第m秒,这里有m=(r - rr + T) mod p(秒) 。p的定义见上。mod是求余运算。根据m的值,我们可以推算出该路口的红绿灯状态——是哪种颜色的,剩余几秒。
  以题目描述给出的样例来说明。已知,出发时路口1的红绿灯状态是红灯、剩余5秒。红绿灯变换规律是红灯30秒,绿灯30秒,黄灯3秒,红绿灯变换周期的耗时是:30 + 30 + 3秒 = 63秒。从开始亮红灯算起,红绿灯变换周期已经经过了30 - 5 = 25秒,加上路段1用时10秒,到达红绿灯变换周期内第35秒((25 + 10) mod 63 = 35)。红绿灯变换周期开始后的第35秒是绿灯。
  
(2)假设出发时,路口的红绿灯状态是绿灯剩余gg秒,经过T秒后,该路口的红绿灯处于变换周期的第几秒??假设红绿灯变换规律是红灯30秒,绿灯30秒,黄灯3秒,绿灯剩余gg秒,是红绿灯变换周期开始后的第(30 + 30 - gg)秒,再过T秒,是第m =(60 - gg + T) mod 63秒。
(3)假设出发时,路口的红绿灯状态是黄灯剩余yy秒,经过T秒后,该路口的红绿灯处于变换周期的第几秒??先求出T秒后的时刻,处于红绿灯变换周期内的第几秒。假设红绿灯变换规律是红灯30秒,绿灯30秒,黄灯3秒,黄灯剩余yy秒,是红绿灯变换周期开始后的第(30 + 30 + 3 - yy)秒,再过T秒,是第m =(63 - yy + T) mod 63秒。
(4)已知红绿灯处于变换周期第m秒,该如何推算出路口的红绿灯状态——是哪种颜色的,剩余几秒?又该如何计算通过该路口的耗时是多少秒?假设红绿灯变换规律是红灯30秒,绿灯30秒,黄灯3秒,分三种情形:
0 <= m <30,结果是红灯,剩余30 - m秒。 通过该路口的耗时是30-m秒。
30 <= m < 60,结果是绿灯,剩余30 + 30 - m秒。 通过该路口的耗时是0秒。
60 <= m < 63,结果是黄灯,剩余30 + 30 + 3 - m秒。通过该路口的耗时是63-m+30秒。

必须注意: int 最大也就 1e9 ,但是按照题目要求,t 不超过 1e6。 n ≤ 1e5 。t*n=1e11 超出 int 范围 ,所以time必须使用 long long类型。

#include<stdio.h>
#include<cmath>
#include<algorithm>
#include<vector>
#include<stack>
#include<string>
#include<iostream>
using namespace std;

int r,g,y;
int main(){
    int n;
    int k,time;
    long long sum=0;
    scanf("%d%d%d",&r,&y,&g);
    scanf("%d",&n);
    int p;
    for(int i=0;i<n;i++){
        scanf("%d%d",&k,&time);
        if(k==0){
            sum+=time;
            continue;
        }
        else if(k==1){
            p=(r-time+sum)%(r+g+y);
        }
        else if(k==3){
            p=(r+g-time+sum)%(r+g+y);
        }
        else if(k==2){
            p=(r+g+y-time+sum)%(r+g+y);
        }

        if(p<r){
            sum+=r-p;
        }
        else if(p<r+g){
            sum+=0;
        }
        else{
            sum=sum+r+r+g+y-p;
        }
    }
    printf("%lld\n",sum);
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值