Fork me on GitHub

无重复抽牌

【问题描述】
    假定有一定数量的牌,每次随机抽取,问如何保证每次抽到的牌不重复直到抽完所有的牌。
 
【解题思路】
    假定有N张牌,每次随机抽一张牌,看完之后将其与这副牌的最后一张牌交换,更新然后在前N-1张牌中再次随机抽取一张,直到N-1为0 结束,这样保证可以抽完所有不一样的牌,时间复杂度保持在O(1)。
【代码实现】
 1 #include <iostream> //for cout()
 2 #include <vector> //for vector
 3 #include <stdlib.h>//for srand() and rand()
 4 #include <time.h> //for time()
 5 
 6 using namespace std;
 7 
 8 void swap(int&a, int &b)
 9 {
10     int temp = a;
11     a = b;
12     b = temp;
13 }
14 
15 int main(void)
16 {
17     const int num = 100;
18     vector <int> vecfrom;
19     vector <int> vecto;
20     int i;
21     for (i = 0; i < num; i++)
22     {
23         vecfrom.push_back(i+1);
24         cout<<vecfrom[i]<<" ";
25     }
26     cout << endl;
27 
28 
29     for (i = 0; i < num; i++)
30     {
31         //利用系统时间作为随机数的种子,这样每次随机得到的结果不一样
32         srand((unsigned)time(NULL));
33         //产生抽排位置的随机数
34         int temp = rand() % (num - i);
35         //将抽到的牌依次压入vector
36         vecto.push_back(vecfrom[temp]);
37         //将抽到的牌与最后一张牌交换位置
38         swap(vecfrom[temp], vecfrom[num - i - 1]);
39         //输出当前抽牌结果
40         cout << vecto[i] << " ";
41     }
42     cout << endl;
43 
44     system("pause");
45     return 0;
46 }
47 
48 
49 /*
50 输出结果:
51 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
52 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 5
53 7 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
54 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
55 81 94 9 23 37 51 65 79 1 16 31 46 61 76 5 21 96 53 69 4 85 38 55 72 13 90 49 67
56 87 32 95 92 80 41 88 91 84 58 17 39 82 24 47 77 64 6 75 3 29 100 54 98 56 18 60
57 50 62 86 48 28 68 99 57 12 93 66 40 73 43 44 89 63 74 70 83 78 36 30 45 35 97 59
58 19 27 71 20 33 26 15 25 42 22 34 2 10 11 8 14 52 7
59 
60 */

 

posted @ 2015-12-09 12:43  GeekerLou  阅读(20)  评论(0编辑  收藏  举报