随机数据生成模板

1. 随机生成整数序列

目标:随机生成 n≤105 个绝对值在 109 以内的整数。(可能包含负数)

技巧:

  • 若要同时产生负数,则可以先产生一个 0~2n 之间的随机整数,再减去 n,就得到了 -n~n 之间的随机整数。
  • 若要随机实数,则可以先产生一个较大的随机整数,再用它除以 10 的次幂。
#include<bits/stdc++.h>
#define int long long
using namespace std;
signed main(){
    srand(time(0)); 
    int n=rand()%(int)1e5+1,m=1e9;
    for(int i=1;i<=n;i++){
        int x=rand()%(2*m+1)-m;
        cout<<x<<" ";
    }
    return 0;
} 

也可以随机一个 1~2 之间的随机整数,若随机出来是 1,则输出 x,否则输出 -x。

#include<bits/stdc++.h>
#define int long long
using namespace std;
signed main(){
    srand(time(0)); 
    int n=rand()%(int)1e5+1,m=1e9;
    for(int i=1;i<=n;i++){
        int x=rand()%m,y=rand()%2+1;
        if(y==1) x=-x;
        cout<<x<<" ";
    }
    return 0;
} 

rand 函数也可以这么写:

以下代码中,函数 random(n) 返回 0~n-1 之间的随机整数,并综合考虑了操作系统和编译器环境的差异,对 int 范围内的 n 均能正常工作。

int random(int n){
    return rand()*rand()%n;
}

2. 随机生成区间列

目标:随机生成 m 个 [1,n] 的子区间。(这些区间可作为数据结构题目的操作序列)

#include<bits/stdc++.h>
#define int long long
using namespace std;
int m,n,x;
signed main(){
    srand(time(0)); 
    cin>>m>>n;
    for(int i=1;i<=m;i++){
        int l=rand()%n+1,r=rand()%n+1;
        if(l>r) swap(l,r);
        cout<<l<<" "<<r<<endl; 
    }
    return 0;
} 

3. 随机生成树

目标:随机生成一棵 n 个点的树,用 n 个点 n-1 条边的无向图的形式输出,每条边附带一个 109 以内的正整数权值。

#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,x;
signed main(){
    srand(time(0)); 
    cin>>n;
    for(int i=2;i<=n;i++){
        int fa=rand()%(i-1)+1,val=rand()%(int)1e9+1;
        cout<<fa<<" "<<i<<" "<<val<<endl;    //从 2~n 之间的每个点 i 向 1~i-1 之间的点连一条边 
    }
    return 0;
} 

4. 随机生成图

目标:随机生成一张 n 个点 m 条边的无向图,图中不存在重边、自环,且必须连通,保证 5≤n≤m≤n×(n-1)/4≤106

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+5;
int n,m;
pair<int,int>e[N];    //保存数据 
map<pair<int,int>,bool>h;    //防止重边 
signed main(){
    srand(time(0)); 
    cin>>n>>m;
    //先生成一棵树,保证连通
    for(int i=1;i<n;i++){
        int fa=rand()%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=rand()%n+1,y=rand()%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+1+m);
    for(int i=1;i<=m;i++)
        cout<<e[i].first<<" "<<e[i].second<<endl;
    return 0;
} 

 

posted @ 2020-10-14 14:13  jrmyt  阅读(219)  评论(0编辑  收藏  举报
浏览器标题切换
浏览器标题切换end