CCF篇:201812-2 小明放学 暨CCF考前一天经验总结

本文深入解析了CCF竞赛中一道关于红绿灯的编程题,分享了从40分提升到60分的经验,强调了数据类型选择的重要性,并提供了满分代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

      明天考第十六次CCF,今天下午刷了一下上次考的题。这个第二题,上次考的时候,得了40分,一直以来也没有时间来分析,今天重新把这道题的逻辑写了一遍,发现得了60分,分析了一下上次的代码,才发现当时对测试数据的定义范围N为100,得了40分。这次得了60分,显然是高范围的数据评测有问题。下面是上次40分的代码(代码设计有些冗余):

#include<iostream>
using namespace std;
#define N 100
int a[N][2];
int waitTime(int r,int g,int y,int t,int curC,int restTime){
	int rest;
	int curtime,fintime;
	if(curC==1){
		curtime=r-restTime;
	}else if(curC==3){
		curtime=r+g-restTime;
	}else if(curC==2){
		curtime=r+g+y-restTime;
	}
	fintime=(curtime+t)%(r+g+y);
	if(fintime>=0 && fintime<=r){
		curC=1;
		rest=r-fintime;
	}else if(fintime>r && fintime<=(r+g)){
		curC=3;
		rest=0;
	}else if(fintime>(r+g) &&fintime<=(r+g+y)){
		curC=2;
		rest=(r+g+y)-fintime+r;
	}
	return rest;
}
int main(){
	int r,g,y,n;
	cin>>r>>y>>g;
	cin>>n;
	for(int i=0;i<n;i++){
		cin>>a[i][0]>>a[i][1];
	}
	int sum=0,sumtime=0,rest;
	for(int i=0;i<n;i++){
		if(a[i][0]==0){
			sum+=a[i][1];
			sumtime=sum;
		}else if(a[i][0]==1){
			rest = waitTime(r,g,y,sumtime,1,a[i][1]);
			sum+=rest;
			sumtime=sum;
		}else if(a[i][0]==3){
			rest = waitTime(r,g,y,sumtime,3,a[i][1]);
			sum+=rest;
			sumtime=sum;
		}else if(a[i][0]==2){
			rest = waitTime(r,g,y,sumtime,2,a[i][1]);
			sum+=rest;
			sumtime=sum;
		}
	}
	cout<<sumtime;
	return 0;
}
表示红绿灯的设置。这三个数均不超过 10的六次方。
耗时 t 秒,此处 t 不超过 10的六次方;
评测用例规模与约定
  有些测试点具有特殊的性质:
  * 前 2 个测试点中不存在任何信号灯。
  测试点的输入数据规模:
  * 前 6 个测试点保证 n ≤ 10的三次方。
  * 所有测试点保证 n ≤ 10的五次方。

       通过评测范围,可以知道,t的时间设计10的六次方,在最终计算出来的结果中,只能用long long数据类型来存储t或者结果,这样一遍通过,运行100分!上次得40分真是可惜的一批哦!

       下面配上满分代码来总结经验:

#include<iostream>
using namespace std;
#define N 100000
long long a[N][2];
long long curTime(long long l,long long spend,long long stateRGB,long long r,long long y,long long g){ //计算curtime
	long long state;
	if(stateRGB==1){ //r
		state = r;
	}else if(stateRGB==2){ //y
		state = r+g+y;
	}else if(stateRGB==3){ //g
		state = r+g;
	}
	long long curtime = ((state-l)+spend)%(r+y+g);
	return curtime;
}
long long waitTime(long long curtime,long long r,long long y,long long g){ //计算waitTime 
	long long waittime = 0;
	if(0<=curtime && curtime<r){
		waittime = r-curtime;
	}else if(r<=curtime && curtime<r+g){
		waittime = 0;
	}else if(r+g<=curtime && curtime<r+g+y){
		waittime = r+g+y-curtime+r;
	}
	return waittime;
} 

int main(){
	long long r,y,g,n;
	cin>>r>>y>>g;
	cin>>n;
	for(long long i=0;i<n;i++){
		cin>>a[i][0]>>a[i][1];
	}
	long long sum=0;
	
	for(long long i=0;i<n;i++){
		long long curtime,waittime,spend=sum;
		if(a[i][0]==0){
		    waittime=a[i][1];
		}else{
			long long stateRGB = a[i][0];
			long long l=a[i][1];
			curtime = curTime(l,spend,stateRGB,r,y,g);   //计算curtime
			waittime = waitTime(curtime,r,y,g);	 //计算waitTime
		}
		sum+=waittime;
	}
	cout<<sum;
	return 0;
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值