Loading

【笔记】对拍

通过生成大量数据,比较不同代码的输出结果检验程序正确性。

数据生成器

使用 mt19937 梅森旋转算法,传入纳秒级别的种子,生成较强的随机数,然后在值域内取模。

#include<iostream>
#include<cstdio>
#include<random>
#include<chrono>
using namespace std;
int n;
mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count());
int Rd(int l,int r){
    return (rnd()%(r-l+1))+l;
}
int main(){
    n=Rd(1,1000);
    printf("%d\n",n);
    for(int i=1;i<=n;i++){
        printf("%d ",Rd(1,10000));
    }
    return 0;
}

随机数头文件:randomchrono

如要在负数区间随机,正数取负即可。

比较器

使用 system 函数调用系统控制台命令,>< 为重定向读写,与 cin cout 方向相反。fc 比较两个文件,如果没有差异返回 0,否则返回非 0。

#include<bits/stdc++.h>
using namespace std;
int main(){
    for(int i=1;i<=10000;i++){
        printf("Running on Test #%d\n",i);
        system("data.exe > a.in");
        system("baoli.exe < a.in > a.ans");
        system("zhengjie.exe");
        if(system("fc a.ans a.out")){
            printf("Wrong Answer\n");
            return 0;
        } 
    }
    printf("Accepted\n");
    return 0;
}

正解可以不写重定向输入输出,检查 freopen

检查器

对于一些 Special Judge 题目,我们可能需要手写检验输出结果是否合法的 checker。

可以单独新建一个文件存储 “Correct”,然后像上面一样把输出文件输入到 checker 中,如果合法就输出 “Correct” 之后 fc 比较两个字符串文件。

特殊数据生成

随机图

每条边随机两个点即可,如果有需要用 map 判一下重边。

随机树

方法一,对于每个节点,连到此前随机一个节点上,即添加边 \((i,\operatorname{rand}(1,i-1))\)。期望树高为 \(\log n\)

方法二,对于每条边,随即两个节点 \(x,y\),用并查集判断连通性,如果连通则继续随机直到不连通。期望树高为 \(\sqrt n\)

随机连通图

随机一棵树后,往树上加边。

随机 DAG

随机一个 \(1\sim n\) 的排列当作拓扑序,然后每条边都从小拓扑序连到大。

随机排列可以定义 \(a_i=i\),然后用 shuffle 函数洗牌。

shuffle(a+1,a+1+n,rnd);

algorithm 头文件中。

随机仙人掌

仙人掌为一些环排列在类似一棵树上,每个边只出现在一个环里的图。

可以先随机一棵树,然后随机从一个点开始往上跳,使其有 \(p\) 的概率成功,\(1-p\) 的概率失败,在失败处与起跳节点连边成环。

跳过的点除了失败处不能再被随机到。

环的个数和 \(p\) 都可以按需求调。

随机合法括号序列

先随机排列 \(n\) 个左括号和 \(n\) 个右括号。

然后我们规定左括号 \(+1\) 右括号 \(-1\),由此可以在 \(1\rightarrow 2n\) 的数轴上画出折线图。

在折线图的最低点处断开,把后面一段拼到前面即可。

posted @ 2026-08-24 20:29  Seqfrel  阅读(2)  评论(0)    收藏  举报