卡时

卡时

背景

有的时候,我们的搜索会搜很很很很很久,会\(TLE\)\(TLE\)的分数\(=0\),但是如果你在即将\(TLE\)时输出了当前最优解,分数即可\(\geqslant 0\)。那么这是就需要卡时。

什么是卡时

卡时,顾名思义,卡时间,就是我们要用一个东西记录当前的时间,如果快要超时了,输出当前最优解,结束。

实现

朴素版(错误

#include<bits/stdc++.h>
//#include<ctime>
//如果你不用bits/stdc++.h那么一定要加ctime

using namespace std;

int st;

signed main(){
	
	st = clock();//记录一下当前的时间的
	
	while(1){//假装在搜索
		if(clock()-st >= 0.95) break;
		//如果现在时间-开始时间要超过1s了,退出
	}
	
	cout << 52520 << endl;//输出当前搜索出的最优解
	
	return 0;
	
}

这时,如果你交到洛谷上,你会惊奇的发现,你的每个测试点都在\(1ms\)以内结束了,这是因为洛谷是\(Linux\)系统,算时间是单位用的微秒,\(0.95\)代表的\(0.95‌μs\),也就是不到\(1ms\),那么你也不知道你叫的评测机是什么单位的,这时就要统一单位。

朴素版

我们只要一个东西,CLOCK_PEP_SEC,这个用来存当前系统\(1s\)内时间单位的个数,它就是\(1s\),再乘个\(0.95\)\(950ms\)

#include<bits/stdc++.h>

using namespace std;

int st;

signed main(){
	
	st = clock();//记录一下当前的时间的
	
	while(1){//假装在搜索
		if(clock()-st >= 0.95*CLOCK_PEP_SEC) break;
		//如果现在时间-开始时间要超过1s了,退出
		//CLOCK_PEP_SEC是1s时间单位的个数
	}
	
	cout << 52520 << endl;//输出当前搜索出的最优解
	
	return 0;
	
}

优化版

我们又发现这里有一个实数乘法,众所周知……

如果我们说加法的时间是\(1\),那么减法也是\(1\),乘法呢?
\(100\)
没有那么多,也就\(32\)
除法呢?
\(100\)
没有那么多,也就\(1000\)吧。

这里虽然是乘法,但是是实数,我们想让它成为整数乘法,怎么弄?两边同乘以\(1000\)即可。

#include<bits/stdc++.h>
#include<ctime>

using namespace std;

int st;

signed main(){
	
	st = clock();//记录一下当前的时间的
	
	while(1){//假装在搜索
		if((clock()-st)*1000 >= 950*CLOCK_PEP_SEC) break;
	}
	
	cout << 52520 << endl;//输出当前搜索出的最优解
	
	return 0;
	
}

最终\(dfs\)

#include<bits/stdc++.h>
#include<ctime>

using namespace std;

int st;

void dfs(){
	if(clock()-st*1000 >= 950*CLOCK_PEP_SEC){
		cout << 52520 << endl;//输出当前最优解
		exit(0);//退出整个程序,约等于return 0;
	}
	dfs();
}

signed main(){
	
	st = clock();//记录一下当前的时间的
    
    dfs();
	
	return 0;
	
}

卡多久

\(999\)吗?不行。首先后面还要输出最优解和退出程序,时间不够的退出。其次,评测机波动会导致时间变化。(比如今天一个同学相同代码第一次交\(80\),第二次交直接\(100\)
那就\(950\)吧。其实可以,但是\(CCF\)重测时时限超过\(950ms\)就不给重测了(虽然没有人会去重测,据老师所知,重测没有成功的)。
所以综上所述,大概\(900\)就可以了

posted @ 2024-10-06 20:11  校牌杀手  阅读(24)  评论(0编辑  收藏  举报