很多人考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. Linux 中常用命令

    命令基本格式: 命令提示符:[root@localhost ~]#      root 代表当前的登录用户(linux当中管理员账号是root)      @ 无实际意义      localhost ...

  2. 纯C语言跑分(详细注释)

    #include <stdio.h> #include <time.h>//clock()所属头文件 ;//快排的数据规模 ,N=;//整点.浮点运算的规模 ;//计算圆周率的 ...

  3. JAVA后台框架优化之微服spring boot

    1.为什么要微服? 首先我们目前后台系统业务链目前还是相对不是那么复杂,但随着项目的拆分,业务的快速推进,各项目模块的接口也随之增加,开发的复杂度不断增加,为以后扩展埋下隐患,而规划新的框架目前主要解 ...

  4. react入门参考资料

    ReactJS简介 React 起源于 Facebook 的内部项目,因为该公司对市场上所有 JavaScript MVC 框架,都不满意,就决定自己写一套,用来架设 Instagram 的网站.做出 ...

  5. iOS8模糊效果UIVisualEffectView的使用

    iOS8模糊效果UIVisualEffectView的使用 效果: 源码: // // ViewController.m // EffectView // // Created by XianMing ...

  6. Compare DML To Both REDO And UNDO Size

    SUMMARY you can remember undo rule  the same to redo if you want demo rule that you can look up the ...

  7. python源码学习(一)——python的总体架构

    python源码学习(一)——python的总体架构 学习环境: 系统:ubuntu 12.04 STLpython版本:2.7既然要学习python的源码,首先我们要在电脑上安装python并且下载 ...

  8. php中的雷同方法

    php中又很多的可选语法,比如echo 使用echo()和print()都可以输出文本,他们的不同之处在于print()函数有一个返回值1代表输出成功,0代表输出失败,二echo()就没有返回值了. ...

  9. 【OpenCV】三种方式操作图像像素

    OpenCV中,有3种访问每个像素的方法:使用at方法.使用迭代器方法.使用指针 运行如下程序后可以发现使用at方法速度最快. 代码如下: //操作图像像素 #include <opencv2/ ...

  10. 快速搭建redis单机版和redis集群版

    单机版 第一步:需要安装redis所需的C语言环境,若虚拟机联网,则执行 yum install gcc-c++ 第二步:redis的源码包上传到linux系统 第三步:解压缩redis   tar ...