隨機生成資料
阿新 • • 發佈:2018-11-02
在\(OI\)學習過程中,資料是必不可少的。不管是在\(OJ\)上提交狂\(Wa\)不止時,還是考場上懷疑自己的演算法但出題人給的資料又能正確\(AC\)時,資料都顯得尤為重要。所以我特地寫一篇隨機資料生成的部落格來總結一下。
隨機函式
首先我們需要認識一下\(C++\)自帶的隨機函式\(rand()\)。標頭檔案\(algorithm\)自帶\(srand\)與\(rand\)兩個函式。
使用\(rand()\)函式會隨機返回一個範圍在[0,RAND_MAX]之間的整數。RAND_MAX等於\(2147483647\)也就是\(int\)能儲存的最大的正整數。你想要\(rand\)一個[0,n-1]範圍的數你可以\(rand()\)
隨機生成排列
for(int i=1;i<=n;i++)
a[i]=i;
random_shuffle(a+1,a+n+1);
for(int i=1;i<=n;i++)
printf("%d ",a[i]);
隨機生成若干個區間
for(int i=1;i<=m;i++) {
int l=rand()%n+1,r=rand()%n+1;
if(l>r)swap(l,r);
printf("%d %d\n",l,r);
}
隨機生成樹
下面的\(n\)全部代表點數,\(m\)全部代表邊數。
for(int i=2;i<=n;i++) { int i_father=rand()%(i-1)+1; printf("%d %d\n",i_father,i); }
生成鏈
for(int i=2;i<=n;i++)
printf("%d %d\n",i-1,i);
生成菊花圖
for(int i=2;i<=n;i++)
printf("1 %d\n",i);
隨機生成聯通圖
#include <map>
#include <cstdio>
#include <algorithm>
using namespace std;
int n,m;
map<pair<int,int>,bool> g;
int main() {
scanf("%d%d",&n,&m);
printf("%d %d\n",n,m);
for(int i=2;i<=n;i++) {
int i_father=rand()%(i-1)+1;
g[make_pair(i_father,i)]=1;
g[make_pair(i,i_father)]=1;
printf("%d %d\n",i_father,i);
}
for(int i=n;i<=m;i++) {
int a=rand()%n+1,b=rand()%n+1;
while(g[make_pair(a,b)])a=rand()%n+1,b=rand()%n+1;
g[make_pair(a,b)]=1;g[make_pair(b,a)]=1;
}
}
不要求聯通就不要先建一棵樹了。