思想:
1.首先生成1到n的数组A
2.生成1到n^3的n个数的随机数组P
例如A=<1,2,3,4> P=<36,3,62,19>
3.对p数组进行从小到大的排序(利用快速排序),生成数组P1=<3,19,36,62>
4.根据3中P1的顺序,生成随机数数组A1=<2,4,1,3>
应用:腾讯面试题目
对于一个斗地主游戏,给出一个发牌的算法,让每个人的牌确保随机。
考虑假设有N张牌,要分出来M张牌,给K个人。我能想到的是,N张牌有N种排列,随机产生一种排列,将产生排列的前M张牌依次分给K个人。使用均匀随机排列算法,能够保证:对于N张牌的N!种排列,且得到的任意一种排列的概率都是相同的,即都为1/(N!)。
代码:
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
//快速排序,平均时间复杂度o(nlog2n),最好为o(log2n),最坏为o(n2).是不稳定排序( 交换排序)
int partition(int A[], int left, int right)
{
int pivot = A[left];
while (left < right)
{
if ((left<right) && (A[right] >= pivot))
--right;
A[left] = A[right];
if ((left < right) && A[left] <= pivot)
++left;
A[right] = A[left];
}
A[left] = pivot;
return left;
}
void FastSort(int A[], int left, int right)
{
if (left < right)
{
int pivotloc = partition(A, left, right);
FastSort(A, pivotloc + 1, right);
FastSort(A, left, pivotloc - 1);
}
}
//生成随机数P数组
int* Randomalgorithm(int m,int n)
{
int *P=new int;
srand((unsigned)time(NULL));
for(int i=1;i<=n;i++)
{
P[i]=rand()%(n*n*n-m+1)+m;//生成从m到n^3的随机数
}
return P;
}
int main(void)
{
int n;
printf("要产生从1到n的随机序列,首先请输入n.\n");
scanf("%d",&n);
int *A=new int;
int *key=new int;
int *P1=new int;
for(int i=1;i<=n;i++)
A[i]=i;
int *P=Randomalgorithm(1,n);
printf("排序前P:");
for(int i=1;i<=n;i++)
printf("%d,",P[i]);
printf("\n");
printf("排序后P1:");
for(int i=1;i<=n;i++)
{
P1[i]=P[i];
}
FastSort(P1,1,n);//对P1数组进行排序
for(int i=1;i<=n;i++)
printf("%d,",P1[i]);
printf("\n");
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(P[i]==P1[j])
key[i]=j;
}
}
for(int i=1;i<=n;i++)
P[i]=A[key[i]];
printf("随机排列数组是:\n");
for(int i=1;i<=n;i++)
printf("%d,",P[i]);
return 0;
}
结果: