编程题目的讨论

在1742年给欧拉的信中哥德巴赫提出了以下猜想:任一大于2的整数都可写成三个质数之和。但是哥德巴赫自己无法证明它,于是就写信请教赫赫有名的大数学家欧拉帮忙证明,但是一直到死,欧拉也无法证明。因现今数学界已经不使用“1也是素数”这个约定,原初猜想的现代陈述为:任一大于5的整数都可写成三个质数之和。欧拉在回信中也提出另一等价版本,即任一大于2的偶数都可写成两个质数之和今日常见的猜想陈述为欧拉的版本。把命题"任一充分大的偶数都可以表示成为一个素因子个数不超过a个的数与另一个素因子不超过b个的数之和"记作"a+b"。1966年陈景润证明了"1+2"成立,即"任一充分大的偶数都可以表示成二个素数的和,或是一个素数和一个半素数的和"。

两个素数之和本来就是偶数,也就说找到所有的素数,然后两两相加,时间复杂度o(n*n),需要2n的空间。

知道哥德巴赫猜想答案就出来了吗?
大于6的偶数的确都能用素数和表示, 但是相加的两个数中可能恰恰包含被刨除的3和5考虑了吗? 
没有了3和5, 如果相加的两个素质只能用相同的两个素数相加, 题里允许了吗? (比如14, 不能3+11, 那么7+7允许吗)

扔出一个哥德巴赫猜想就好像答案已经出来了, 连题意和输入都不能静下心仔细确定好的, 这个比不懂某方面知识捉急多了

 

概念题,每次抽取只会有三个结果:
一红一蓝
两蓝
两红

由于每次取球只能是0个或者2个,所以最后剩球只会是两个,那么题意是要求得到最后一次取球为一红一蓝的概率。

为了最后剩余一红一蓝,则前面不能出现两蓝的情况,比如第一次出现两蓝,那么剩余18蓝加20红,这样就无论如何不会最后剩余一红一蓝了,最多两红(这里最难理解了,多想一想)

所以,要想最后剩余一红一蓝,必须每次取出的都是一红一蓝,那么概率是:
(1/20 * 20/39) * (1/19 * 19/38) * (1/18 * 18/37)
即:
(1/(n - k) * (n - k)/(2*n - 1 - k))
n=20
k=0,1,2,...,18

上面稍有点问题,结论应该是:
要想最后剩余一红一蓝,必须每次取出的都是一红一蓝或者两红,那么概率是:
(1/20 * 20/39 + 1/20*19/39) * (1/19 * 19/38 + 1/20*19/39) ...

 

 

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <math.h>
 4 #include <time.h>
 5 
 6 #include <set>
 7 #include <vector>
 8  
 9 #define MAXNUMBER 1000000
10 
11 bool is_prime (int x)
12 {
13     int i,t;
14     if (x<=1 || 0==x%2)
15     {
16         return false;
17     }
18     t = (int)sqrt (x+0.0f);
19     for (i=3;i<=t;i+=2)
20     {
21         if (0 == x%i)
22         {
23             return false;
24         }
25     }
26     return true;
27 }
28 
29 int main(void)
30 {
31     std::vector<int> prime_Value;
32     prime_Value.reserve(50000);
33     std::set<int> value_set;
34     prime_Value.push_back(7);
35     prime_Value.push_back(11);
36 
37     int max_sum=18;
38     time_t timenow =time(NULL);
39     for (int i =13 ;i < MAXNUMBER;i+=2)
40     {
41         if (is_prime(i))
42         {
43             int max_prime =prime_Value[prime_Value.size()-1];
44             std::set<int> tmp_set;
45 
46             for (int j = max_sum+2 ;j<max_prime+i;j+=2)
47             {
48                 tmp_set.insert(j);
49 
50             }
51             for (int j =0 ;j< prime_Value.size();j++)
52             {
53                 int tmp_value = prime_Value[j]+i;
54                 std::set<int>::iterator iter =  value_set.find(tmp_value);
55                 if (iter!=value_set.end())
56                 {
57                     value_set.erase(iter);
58                 }
59                 else
60                 {
61                     iter =  tmp_set.find(tmp_value);
62                     if (iter!=tmp_set.end())
63                         tmp_set.erase(iter);
64                 }
65 
66             }
67             prime_Value.push_back(i);
68             value_set.insert(tmp_set.begin(),tmp_set.end());
69 
70             max_sum = max_prime+i;
71 
72         }
73     }
74     int spend = time(NULL)-timenow;
75     printf("spend %d sec ,prime_size=%d,value_size=%d\n",spend,prime_Value.size(),value_set.size());
76     std::set<int>::iterator iter;
77     int max_prime =prime_Value[prime_Value.size()-1];
78     int sec_prime =prime_Value[prime_Value.size()-2];
79     printf("max_prime= %d,sec_prime=%d \n",max_prime,sec_prime);
80 
81     for (iter=value_set.begin();iter!= value_set.end();iter++)
82     {
83         printf("%d is not in list \n",*iter);
84     }
85     getchar();
86     return 0;
87 
88 
89 }

今天下午面了百度,其中两题是这样的,我都没有回答出来。
概率题:一个篮子里装着20个红球和20个蓝球,每次从中取出2球,如果取出的2球颜色是不一样的,那么放回红球,取出蓝球;如果取出的2球的颜色是一样的,则都不放回,将2球都取出;不断重复以上步骤。问题:求最后一次取球恰好只取到一个红球的概率。

算法题:给你一个自然数N,求[6,N]之内的所有素数中,两两之和为偶数的那些偶数。(直接枚举的话应该是O(n^2))。我的解法如下,是直接枚举的。

 

 1 /* 百度面试题 */
 2 #include <math.h>
 3 #include <stdio.h>
 4 #include <stdlib.h>
 5 #define N (20000)
 6 #define M (N/2)
 7 
 8 static int primes[M]; /*编译器初始化了0*/
 9 static int sums[M*M]; /*任意两素数之和*/
10 int my_cmp (const void * a, const void * b);
11 
12 /* 判断一个数是不是素数,是素数则返回它自己;否则返回0 */
13 int is_prime (int x){
14     int i,t;
15     int ans = 0;
16     if (x<=1 || 0==x%2){
17         return ans;
18     }
19     t = (int)sqrt (x);
20     for (i=3;i<=t;i+=2){
21         if (0 == x%i){
22             return ans;
23         }
24     }
25     return (ans = x);
26 }
27 
28 /* 保存区间的素数到全局数组primes */
29 void primes_in (int low, int high){
30     int i=0,j=low;
31     while (j<=high){
32         if (is_prime (j)){
33             primes[i++]=j;
34         }
35         j++;
36     }
37 }/*数组中的非零元素就是区间中的素数 */
38 
39 /*求区间中素数的和并打印出来 */
40 void solve (int left, int right){
41     int i,j,k;
42     int t;
43     primes_in (left,right);
44     for (t=0; t<M; t++){
45         if (!primes[t]){
46             break;
47         }
48     }
49     for (k=0,i=0; i<t; i++){
50         for (j=i; j<t; j++){
51             sums[k++]=primes[i]+primes[j];   
52         }
53     }
54     /*排序*/
55     qsort (sums, k, sizeof (int), my_cmp); 
56     /*去重*/
57     i=0;
58     for (j=i+1; j<k; j++){
59         if (sums[j] > sums[i]){
60             sums[++i] = sums[j];
61         }
62     }  
63     /*打印*/
64     for (j=0;j<=i;j++){
65         printf ("%d, %d\n", j+1, sums[j]);
66     }
67 }
68 
69 int my_cmp (const void * a, const void * b){
70     return (*(int *)a - *(int *)b);
71 }
72 
73 
74 /* 程序入口 */
75 int main (){
76     solve (6,N);
77     return 0;
78     
79 }

 

 

posted @ 2013-08-16 22:18  herizai007  阅读(937)  评论(0编辑  收藏  举报