隨機資料生成模板
阿新 • • 發佈:2020-10-14
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(inti=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; }