如何造数据及对拍

0成本学习方式,扔给队友,队友会了就是我会了

造数据

生成随机数

使用rand()类即可生成随机数:

#include <bits/stdc++.h>
#define int long long //懒狗必备
using namespace std;
//生成[0, x)的随机数范围
int random(int x) {
    return rand() % x;
}
//生成[l, R]的随机数范围
int random(int l, int r) {
    return rand() % (r - l + 1) + l;
}
//对开闭有要求可以自行调整
signed main() {
    //这行代码一定要写,unsigned可以直接宏掉LL,写int会报错,还能保证每次输出都是随机的数,不然编译后每次你的序列都是一样的
    srand(unsigned(time(0)));
    for(int i = 1; i <= 10; ++i) cout << random(100) << endl;
    for(int i = 1; i <= 10; ++i) cout << random(1e17, 1e18) << endl;
    return 0;
}

生成输入输出文件

如何生成一般题目需要的数据文件,首先我们先生成输入数据:刚开始我们的项目结构是这样的:

执行完下面的代码后

#include <bits/stdc++.h>
#define int long long
using namespace std;
int random(int x) {
    return rand() % x;
}
signed main() {
    srand(unsigned(time(0)));
    /*
     *重定向输出, 输出到文件下, test.in会在项目结构下自动生成
     *如果你使用IDE不行,自己创建一个空文本, 然后复制路径
     */
    freopen("test01.in", "w", stdout); //后缀名一般为.in
    for(int i = 1; i <= 10; ++i) cout << random(10) << endl;
    return 0;
}


我们来打开这个文本看一下,是否输出到里面了:

然后就是使用我们的标程(即Ac代码)读入刚才生成的输入数据,产生输出数据:

#include <bits/stdc++.h>
#define int long long
using namespace std;
signed main() {
    freopen("test01.in", "r", stdin); //设置 cin scanf 这些输入流都从 test01.in
    freopen("test01.out", "w", stdout); //设置 cout printf 这些输出流都输出到 test01.out里面去
    //下面读入数据,写标程代码,以输出十个数和为例
    int sum = 0;
    for(int i = 1, x; i <= 10; ++i) cin >> x, sum += x;
    cout << sum << endl;
    return 0;
}

这样我们就学会造数据啦,将文件打包压缩到oj上就可以了。

特殊数据的造法

如果是极端数据,一般需要自己捏,随机数不一定能随出来。
1、字符
这个无需刻意学,自己用随机数就可,转化成char,如果输出的是汉字,注意字符集的设置。
2、树

for(int i = 2; i <= n; ++i) {//生成n - 1条边
    int u = random(i - 1) + 1;
    int w = random(1e5) + 1;//随机权值
    cout << u << " " << i << " " << w << endl;//随机往前面结点挂边
}

3、图

//无向图为例
pair<int, int> e[N];
map<pair<int, int>, bool> h;
//生成一棵树,保证连通
for(int i = 1; i < n; ++i) {
    int fa = random(i) + 1;
    e[i] = make_pair(fa, i + 1);
    h[e[i]] = h[make_pair(i + 1, fa)] = 1;
}
//生成剩余的m - n + 1条边
for(int i = n; i <= m; ++i) {
    int x, y;
    do {
        x = random(n) + 1, y = random(n) + 1;
    } while(x == y || h[make_pair(x, y)]);
    e[i] = make_pair(x, y);
    h[e[i]] = h[make_pair(y, x)] = 1;
}
//随机打乱输出
random_shuffle(e + 1, e + m + 1);
for(int i = 1; i <= m; ++i) cout << e[i].first << " " << e[i].second << endl;

4、区间询问
直接随出L,R,如果R > L,记得swap,这里不放代码了。

对拍

很多时候,我们题交一份代码经常wa,或者需要造一些奇怪的数据的时候,需要使用到对拍。
如果一道题错了很多次,
1、造一份这道题的数据data.txt。(如果这道题很难造 那么G)
2、自己有标准代码或者能写一份正确的暴力代码。
3、然后分别将data.txt输入两份代码,生成两份输出数据,out01.txt、out02.txt。
4、新建一个txt,使用window批处理文件,会自动对比这两份输出数据的差异。
具体演示:

例子:题目要求是计算十次 a + b, 你写成了a - b,这个例子过于弱智,看个乐就行。

1、新建一个文件夹用于存放文件

2、造一份数据出来

srand(unsigned(time(0)));
freopen("E:\\AcCode\\duipai\\data.txt", "w", stdout);
for(int i = 1; i <= 10; i++) {
    cout << random(10) << " " << random(20) << endl;
}

3、生成两份输出数据,out01.txt、out02.txt,错的,对的
错误的

srand(unsigned(time(0)));
freopen("E:\\AcCode\\duipai\\data.txt", "r", stdin);
freopen("E:\\AcCode\\duipai\\out01.txt", "w", stdout);
for(int i = 1, a, b; i <= 10; ++i) {
    cin >> a >> b;
    cout << a - b << endl;
}

正确的

srand(unsigned(time(0)));
freopen("E:\\AcCode\\duipai\\data.txt", "r", stdin);
freopen("E:\\AcCode\\duipai\\out02.txt", "w", stdout);
for(int i = 1, a, b; i <= 10; ++i) {
    cin >> a >> b;
    cout << a + b << endl;
}


4、新建一个txt,写入以下代码

@echo off
fc out01.txt out02.txt
pause

5、后缀名改为.bat, 然后运行(直接打开)这个文件即可看到差距。

来个三连!!!

posted @ 2022-09-27 19:53  std&ice  阅读(327)  评论(2编辑  收藏  举报