1. 程式人生 > 實用技巧 >隨機資料生成模板

隨機資料生成模板

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(x,y)]=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;
}