很多人考noip之类的比赛永远会发生一些奇怪的问题

比如说下面这两位(来自我的两位学长)

sliver n:spli,考得怎样啊?

spli:就那样啦,day1T1没推出来规律,别的还好

silver n:看来你省一高分预定啊

几周后。。。

silver n:分出来了吗?

spli:出来了。。。

silver n:怎么了?

spli:别提了,day2T2挂了,没拿上省一

silver n:嗯???你写的不是正解么?

spli:是啊,可是我边界处理出锅了。。

silver n:。。。

好吧,以上是一个本能进队的大佬无奈退役的经历

同时也告诉了我们检查的重要性

废话少说,进入正题

很多时候我们在考场上总是会手残的犯一些错误(比如边界什么,大小写,变量名)

然后你眼残也看不出来,怎么办呢?

我们今天就要讲这些的克星对拍

对拍不能解决一切问题,但却可以解决你解决不了的问题

工具:一台电脑(没错,只用一台电脑)

软件:命令提示符(别告诉我你家电脑上没有这个东西),记事本,c++编译器

下面我们来开始愉快的对拍之旅(这里讲的是关于命令提示符的对拍,大家可以把他搬到c++里(用windows库),但容易出锅(我就出过几次))

(注意,本篇文章默认使用windows系统!!!)

首先,我们先掌握几个前置技能:

1.编写你的认为是正解的程序和暴力程序(你要不会我也没办法了)

2.数据生成器(也就是随机数)

先说随机数

相信大家一般用随机数都是用

#include<cstdlib>

库中的rand()函数,但这显然是不正确的

因为rand()是伪随机数!!!

只要出题人想卡你,跑两遍随机数,打个表,数据避开一下

你的答案一不小心就出锅了

所以,今天我们学如何生成真正的随机数:

首先,我们先明确一点,c++里面的随机数是一种算法

这个算法依赖于一个被称为种子的数据

种子一般情况下是1

由于算法是固定的,所以种子不同,随机数也就不同

所以关键就在于随机数种子的生成。

我们一般使用时间种子生成器(time()函数)

(如果以时间为种子,这个种子一秒钟一变,出题人想卡你的话那他简直是疯了)

怎么用呢?看下面:

首先我们要添加time()的头文件:

#include<ctime>

之后,我们就可以使用这个函数了!!看图

有了种子,我们就要利用种子生成随机数了。

我们有请srand()函数登场。

srand()函数类似于cmp或者重载运算符函数之类的函数

在这里他被用于改变种子

用法:

先加头文件(和rand()一样):

#include<cstdlib>

然后看下面:

其实还有一点,是文件操作,我就默认你们会了(每次考试都会用)

好了,该有的都有了,下面我们就来一个制造数据的实例吧!

我以洛谷P3372【模板】线段树 1为例:

题面:

题目描述

如题,已知一个数列,你需要进行下面两种操作:

1.将某区间每一个数加上x

2.求出某区间每一个数的和

输入输出格式

输入格式:

第一行包含两个整数N、M,分别表示该数列数字的个数和操作的总个数。

第二行包含N个用空格分隔的整数,其中第i个数字表示数列第i项的初始值。

接下来M行每行包含3或4个整数,表示一个操作,具体如下:

操作1: 格式:1 x y k 含义:将区间[x,y]内每个数加上k

操作2: 格式:2 x y 含义:输出区间[x,y]内每个数的和

输出格式:

输出包含若干行整数,即为所有操作2的结果。

数据规模:

对于30%的数据:N<=8,M<=10

对于70%的数据:N<=1000,M<=10000

对于100%的数据:N<=100000,M<=100000

(数据已经过加强^_^,保证在int64/long long数据范围内)

由题目可知,我们要造的是n,m,n个原始节点,m次操作,且节点值的和在long long范围内,n,m<=100000

具体实现请看代码:

#include<iostream>
#include<cstdio>
#include<ctime>
#include<cstdlib>
#define rii register int i
#define p 100000
using namespace std;
long long seed;
long long n,m;
int main()
{
freopen("xds1.in","w",stdout);//文件操作,得到输入文件
seed=time();
srand(seed);
n=rand();//windows下rand()max为32768,为了有一定的强度,我们乘一下
n*=n;//n,m这里你也可以手动取值
n%=p;
m=rand();
m*=m;
m%=p;
// n=10,m=10;
printf("%lld %lld\n",n,m);
for(rii=;i<=n;i++)//制造原始大小
{
long long out=rand();
out*=;
long long fh=rand();//添加负数
if(fh%==)
{
fh=;
}
else
{
fh=-;
}
printf("%lld ",out*fh);
}
printf("\n");
for(rii=;i<=m;i++)//制造操作
{
long long cz=rand();
if(cz%==)//生成修改操作的数据
{
printf("1 ");//生成添加操作的数据
long long fh=rand();//添加负数
if(fh%==)
{
fh=;
}
else
{
fh=-;
}
long long l=rand(),r=rand(),val=rand();
l*=l;
l%=n;
if(l==)
{
l=;
}
r*=r;
r%=n;
if(r==)
{
r=;
}
val*=fh;
val*=;
if(l>r)
{
swap(l,r);
}
printf("%lld %lld %lld\n",l,r,val);
}
else //生成查询操作的数据
{
printf("2 ");
long long l=rand(),r=rand();
l*=l;
l%=n;
if(l==)
{
l=;
}
r*=r;
r%=n;
if(r==)
{
r=;
}
if(l>r)
{
swap(l,r);
}
printf("%lld %lld\n",l,r);
}
}
//区间和最大值上限在我写的数据中为
//32768*100000*100000*2333=764477440000000000
// long long max=2^63-1=9223372036854775807,确保符合题意
}

下面是一组我造出来的数据(为了能放的下,n,m我手动设定为10)

10 10
1632165 90637 4875292 6168675 -6979981 3452128 5007170 -6946895 3268524 1131914
1 4 9 6775873
1 4 9 -1544790
1 6 9 6904023
2 5 6
1 1 4 3328405
1 1 6 2169929
2 4 9
1 1 9 3784852
1 1 6 -1164534
1 1 4 -5979013

怎么样?还不错吧?

3.windows文件操作(windows script语言)

这个大家可能不太熟悉,

不过没关系,我会把可能用到的都讲一遍。

(1)文件比较操作:

也就是比较两个文件,判断这两个文件是否相等

我们一般用命令提示符(cmd.exe)操作(也可以写成.bat批处理文件)

如果两个文件相等,他会返回:(有点不智能,无法忽略空格和回车)

如果不相等,他会返回错误的地方:

很好用吧?

(2)启动程序操作

RT,就是启动一个位于与cmd/.bat同文件夹内的程序(其实也可以启动不同文件夹里的,不过要写路径)

代码极短:

就是这样。

(3)暂停操作

你会发现:哎,我的代码没错啊,为什么闪退了?

的确,你没写错

但电脑默认执行完一个操作后自动跳出

所以看起来像闪退。

怎么办呢?

我们可以让电脑完成操作后“暂停”一下。

看代码:

电脑会停下来,直到你按一下键盘

4.在c++语言中引入windws script语言:

这个很重要,因为循环什么的在windows script中很难实现

我们首先要在c++中引用头文件:

#include<windows.h>

引用了这个头文件,我们就可以使用system()函数

样例:

system("pause");

在括号和引号中间写你要执行的window语句即可

5.Sleep挂起操作

有的时候,你会发现对拍将两个正确的输出拍成错的了,这是为什么呢?

很简单,比如说上面那道线段树,正解跑一秒,暴力4~5秒

但程序的命令行才不管你跑了几秒,执行完一个立马执行下一个

所以喽,和可能你的数据还没来得及输出完,就已经被比较了

不错才怪呢!

所以我们要写Sleep()函数(注意S大写!!)

暂停一段时间程序的运行,让你的暴力好好跑一跑

怎么实现呢?很简单,看下面:

头文件:

#include<windows.h>

 实现方法:

好啦,前置技能讲完了,下一步我来讲实例!

我们的实例还是上面的线段树1。

首先,我们先将“正解”程序,暴力程序,数据生成器和对拍程序写好,放在一个文件夹里

下面我给出对拍程序的源代码(注意,数据生成器,“暴力”和“正解”务必提前编译(也就是要exe)):

#include<iostream>
#include<cstdio>
#include<windows.h>
using namespace std;
int main()
{
int cnt=;
while(cnt<=)
{
cnt++;
system("start sjmaker.exe");//启动数据生成器
Sleep();//等待数据输出(极限数据输出大约0.5s)
system("start baoli.exe");//启动“正解”和”暴力“
system("start zhengjie.exe");
Sleep();//这个时间取决于你写的暴力的最坏时间
if(system("fc baoli.out zhengjie.out"))//如果出锅,就停下来
{
system("pause");
break;
}
}
}

OK, Debug完成!你可以去写别的题了,只要时常回来看一看有没有bug就行了。

 如果你不想用c++的话......

当然,我们不会强制你使用c++引用系统命令,我们也可以直接用windows批处理文件来解决。

首先,先说明一下,.bat批处理文件就是windows命令,只不过放到了记事本里,又改了一下后缀名。。。

这里先补充一个操作:windows中的暂停操作(其实不是暂停,不过和暂停一个效果):

我们用这条语言来挂起程序一段时间

下面我们来看实例:

 1.首先,我们新建一个文本文档,在里面编写系统语言:

(此处为源代码,和c++中基本一致)

2.然后将文件后缀名改为.bat

运行后即可看到结果

你可能会问:这不是有bug么?只能运行一次???

的确,这点不太友好,因为windows命令提示符中不支持循环。。。

所以,你有两条路可走,一条是在c++的循环中  system(“start duipai.bat”);

(与其这样还不如在c++里直接写呢。。)

还有一种是自调用bat(有些危险,手滑勿用)

我们在bat文件的最后一行写下这样一行代码:

start duipai.bat

他就会在执行完上一个程序之后自动重复执行

(warning!!前面的暂停时间必须要开大,否则快速的重复执行会让你死机!!(你的手都来不及关))。

番外篇:clock()函数

很有可能我们通过对拍,已经知道这个的答案是对的了,但是,我们有时候又担心卡时间,怎么办呢?

我们可以使用clock()函数

顾名思义,这是一个计时函数

他大体上是这样的:

先定义变量:

clock_t start,stop;

在代码的开始各跑一个clock()函数,比如说:

#include<time.h>
#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
clock_t start,end;
start=clock();
//这里写你的源代码
//。
//。
//。
//。
end=clock();
cout<<end-start;
}

这样就读出了时间(单位:毫秒ms)

当然,这样跑是会占用一定cpu时间的,如果发现略有超时(比如1000ms你跑了1050ms),别怕,正常情况还是能过的

当然,大家如果有更好的方法,欢迎私信联系

debug?用对拍!的更多相关文章

  1. 2019icpc银川站 复现赛

    打了计蒜客上的银川重现赛,总体感觉难度上确实比平时区域赛要低上一些. 这里补一下F题和G题的思路和代码. upd:I题也补了,理解差不多都在注释里. F题        做法,玩一下n=10的样例就出 ...

  2. jmeter sampler maven项目排错记

    eclipse 创建的maven项目,引入jar包之后出现红色叹号,一直找不到原因,连main方法都无法运行,提示找不到类: 错误: 找不到或无法加载主类 soapsampler.SoapSample ...

  3. 《自拍教程18》adb_Android设备debug连接工具

    adb命令介绍 做Android App测试,Android手机系统测试, 还有很多Android终端产品(手表,车载,智能电视,智能手表等) 都必须用adb命令,通过USB接口,与Android设备 ...

  4. 基于python脚本的对拍debug

    首先,这是python脚本 import os; for i in range(0,20): print ("Case:"+str(i)); print ("random ...

  5. Debug JDK变量显形

    本文面向的朋友 本文主要说明在使用Eclipse Debug JDK时,看不到变量值的解决办法. 如果您看到上面绿色字体表示不敢兴趣,请一定果断back,如果您不爽,请在下面使劲的拍. Debug J ...

  6. 趣拍SDK接入问题Android

    Android接入趣拍问题. 大部分android开发者第一次下载SDK后,特别是导入到eclipse后,可以运行工程,但点击app中的record没反映,每次点击record按钮 会出现如下log. ...

  7. 用Visual Studio Code Debug世界上最好的语言

    前言 这阵子因缘巧合接手了一个辣鸡项目,是用世界上最好的拍黄片写的,项目基本是另一个小伙伴在撸码,我就兼职打杂和发布做点运维的工作. 然后昨天项目上了测试版之后,一用起来Error满天飞了.让小伙伴查 ...

  8. DEBUG技巧-设定合适的日志级别

    有些技能只有踩过坑的人才能够掌握,能用来避免后来的坑,很多时候是用凌晨的时间换来的,我们通常把他叫做经验. 故事 这个一个关于springmvc的坑的故事. 某天晚上本打算一个小功能分分钟搞定上线,但 ...

  9. 关于c++对拍的办法

    众所周知,在\(oi\)学习以及考试中,对拍是一件非常重要的事. 有了对拍后,我们可以利用它发现代码上的一些非常难看出来的错误. 编写对拍程序一般有两个办法. 方案一 编写一个对拍的\(cpp\),并 ...

随机推荐

  1. Android深入理解Context(三)Context完全解析

      1· Context类型        我们知道,Android应用都是使用Java语言来编写的,那么大家可以思考一下,一个Android程序和一个Java程序,他们最大的区别在哪里?划分界限又是 ...

  2. Tinker + Bugly + Jenkins 爬坑之路

    前阵子 Android 端的线上崩溃比较多,热修复被提上日程.实现方案是 Tinker,Jenkins 打包,最后补丁包上传到 Bugly 进行分发.主要在 Jenkins 打包这一块爬了不少坑,现记 ...

  3. 排查在 Azure 中创建、重启 Windows VM 或调整其大小时发生的分配失败

    创建 VM.重新启动已停止(解除分配)的 VM 和重设 VM 大小时,Azure 会为订阅分配计算资源. 执行这些操作时,即使尚未达到 Azure 订阅限制,也可能偶尔收到错误. 本文说明一些常见分配 ...

  4. Mybatis源码解析优秀博文

    最近阅读了许久的mybatis源码,小有所悟.同时也发现网上有许多优秀的mybatis源码讲解博文.本人打算把自己阅读过的.觉得不错的一些博文列出来.以此进一步加深对mybatis框架的理解.其实还有 ...

  5. zbrush书法文字硬边雕刻

    方法的重点在与边缘环的操作以及模型网格的数量. 1.通过ZAppLink功能可以把制作的文字书法映射到模型上去. 2.遮罩,按照颜色强度遮罩. 3.分组,按照颜色分组.单独显示文字部分的分组.按Ctr ...

  6. php给$_POST赋值会导致值为空

    在调试一个程序的时候发现很奇怪的现象,post传过来的值再某些地方为空,先看下面的代码 <?php if($_POST['submit'] == 'Add'){ if($_POST['type' ...

  7. 定义类、System.Object对象、构造函数与析构函数、抽象类与静态类

    一.类定义 class MyClass { //类成员 } 1.访问级别 默认访问级别为internal(内部类),也可以是public(公共类) internal(内部类):当前项目中的代码才能访问 ...

  8. 【RabbitMQ】3、工作队列模式(work模式)

    上一篇博客的作为rabbitMQ的入门程序,也是简单队列模式,一个生产者,一个消费者,今天这篇博客介绍work模式,一个生产者,多个消费者,下面的例子模拟两个消费者的情况. 图示:         一 ...

  9. PhoneGap模仿微信摇一摇功能

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  10. 【[SHOI2007]善意的投票】

    直接是最小割啊 设最终还和\(S\)相连表示睡觉,和\(T\)相连表示不睡觉 如果这个人想睡觉,那么就从源点向它连\(1\)的边,表示割掉这条边选择不睡觉的代价为1 如果这个人不想睡觉的话,就向汇点连 ...