今天hxd给了我一个问题,如下:
k个数随机分配给k个学生,即生成一个随机的全排列。
1.首先想到的是在1~k中随机生成若干数,直至出现k个不同的数,最好的情况可以达到O(n),最坏会陷入死循环。
2.另外一种思路是先生成1~k的全排列,然后随机找出一组全排列,但复杂度高达O(2^n),遂胎死腹中,附上全排列代码
#include<iostream>
using namespace std;
int path[10];
int vis[10];int n;
void dfs(int u)
{
if(u==n)
{
for(int i=0;i<n;i++)
cout<<path[i]<<" ";
cout<<endl;
}
for(int i=1;i<=n;i++)
{
if(!vis[i])
{
vis[i]=1;
path[u]=i;
dfs(u+1);
vis[i]=0;
}
}
}
int main()
{
cin>>n;
dfs(0);
return 0;
}
3.算法改进:
在1~k中随机生成一个数作为数组的索引,将该索引对应的值输出,将该索引于第k位交换,再用相同的方法1~k-1中随机产生,直到找到k个数,算法优化到O(n).
#include<iostream>
#include<vector>
#include<algorithm>>
using namespace std;
int n;
int main()
{
cin>>n;
vector<int>a,b;
a.push_back(0);
for(int i=1;i<=n;i++)
a.push_back(i);
int t=n;
for(int i=1;i<=n;i++)
{
int x=1+rand()%t;
b.push_back(a[x]);
swap(a[x],a[t]);
t--;
}
for(int i=0;i<n;i++)
printf("%d ",b[i]);
return 0;
}
写在后面:
如有错误,欢迎巨巨斧正!