IQ

【微--策--略】

1. 五个洞排成一排,其中一个洞里藏有一只狐狸。每个夜晚,狐狸都会跳到一个相邻的洞里;每个白天,你都只允许检查其中一个洞。怎样才能保证狐狸最终会被抓住?

解答:有个问题 错了 下面是少一天的推理 第一天2洞 第二天2洞 都没有的话 证明它在后三个里面 第三天4洞 第四天4洞 都没有的话 证明第三天的时候 它在3号洞 第四天去了2号洞 第五天3洞 它如果不在 它肯定在1号洞 第六天在2号洞抓到它 bingo?

2.  5个海盗分100个金币问题

首先从5号海盗开始,因为他是最安全的,没有被扔下大海的风险,因此他的策略也最为简单,即最好前面的人全都死光光,那么他就可以独得这100枚金币了。 
接下来看4号,他的生存机会完全取决于前面还有人存活着,因为如果1号到3号的海盗全都喂了鲨鱼,那么在只剩4号与5号的情况下,不管4号提出怎样的分配方案,5号一定都会投反对票来让4号去喂鲨鱼,以独吞全部的金币。哪怕4号为了保命而讨好5号,提出(0,100)这样的方案让5号独占金币,但是5号还有可能觉得留着4号有危险,而投票反对以让其喂鲨鱼。因此理性的4号是不应该冒这样的风险,把存活的希望寄托在5号的随机选择上的,他惟有支持3号才能绝对保证自身的性命。 
再来看3号,他经过上述的逻辑推理之后,就会提出(100,0,0)这样的分配方案,因为他知道4号哪怕一无所获,也还是会无条件的支持他而投赞成票的,那么再加上自己的1票就可以使他稳获这100金币了。 
但是,2号也经过推理得知了3号的分配方案,那么他就会提出(98,0,1,1)的方案。因为这个方案相对于3号的分配方案,4号和5号至少可以获得1枚金币,理性的4号和5号自然会觉得此方案对他们来说更有利而支持2号,不希望2号出局而由3号来进行分配。这样,2号就可以屁颠屁颠的拿走98枚金币了。 
不幸的是,1号海盗更不是省油的灯,经过一番推理之后也洞悉了2号的分配方案。他将采取的策略是放弃2号,而给3号1枚金币,同时给4号或5号2枚金币,即提出(97,0,1,2,0)或(97,0,1,0,2)的分配方案。由于1号的分配方案对于3号与4号或5号来说,相比2号的方案可以获得更多的利益,那么他们将会投票支持1号,再加上1号自身的1票,97枚金币就可轻松落入1号的腰包

3. Project Euler15 给定一个20*20的方格,从左上角到右下角的路径有多少条?(只允许向右和向下走)

首先我们来讨论一下2*2方格的情况:

从结点1到结点9的走法:

1-2-3-6-9

1-2-5-6-9

1-2-5-8-9

1-4-7-8-9

1-4-5-6-9

1-4-5-8-9

共有6种不同的走法,仔细的读者会发现,在结点3,6,7,8到结点9的通道只有一种,是的,这将会是以后解决问题的关键之一。

现在我们将方格数推广到n,定义f(n,n)为结点(0,0)到结点(n,n)的通道数。

算法如下:

方法一:递推法

  • 递推公式为f(n,n)=f(n-1,n)+f(n,n-1);
  • 初始化条件:当0 <= i <= n,f(n,i)=1,f(i,n)=1。(初始条件的寻找,还得看读者的观察能力了)

方法二:排列组合

  • f(n,n)=c(n,n+n),其中c(n,n+n)表示n+n中取n

现在我只研究方法一,实现的代码如下:

#include <iostream>
#include <TIME.H>
using namespace std;
#define MAX_X 21
#define MAX_Y 21
/*递归*/
_int64 Recursion()
{
	_int64 a[MAX_X][MAX_Y] ;
	for(int i=0;i<=MAX_X-1;i++)
	{
		a[MAX_X-1][i]=1;
		a[i][MAX_Y-1]=1;
	}
	for (int j=MAX_X-2;j>=0;--j)
		for(int i1=MAX_Y-2;i1>=0;i1--)
			a[j][i1]=a[j+1][i1]+a[j][i1+1];

	return a[0][0];
}
int main()
{
	printf("%I64d",Recursion());
	return 0;
}


 

运行结果:137846528820

算法,虽不是最好,但只为追求更好,还望不吝赐教!!!

*************************************

4.  在一光滑的平面上 左边有m个小球以v的速度向右运动 右边有n个小球以同样的速度向左运动 球的质量相同 且发生完全弹性碰撞 问共碰撞多少次啊

提问者采纳

m*n次(前提是质量相等,否则无解)
左一,右二,撞2次
左二,右二,撞4次
左二,右三,撞6次
。
。
。
左m,右n,撞m*n次

5.  在一光

某同学编了一个ax^2+bx+c=0的程序,任何输入均有输出,请设计测试用例!!

 

设:ax^2 =A;bx=B;c=C;
1.A=0,B=0,C=0; 
2.A+B=0,C=0;
3.A+C=0,B=0;
4.C+B=0,A=0;
这个思路看得懂吧?就是按这个思路去设计。

6

ddd

dddddddd

随笔- 74  文章- 0  评论- 14 

【算法题】rand5()产生rand7()

前两天,睡觉前,偶尔翻起算法导论,看到随机函数这一块内容,里面有一个练习题.

5.1-2 描述random(a,b)过程的一种实现,它只调用random(0,1).作为a和b的函数,你的程序的期望运行时间是多少?

注:random(a,b)为产生a,a+1,a+2,...,b的函数发生器,且产生各整数的概率相等,同为1/(b - a + 1).

看到这个题目时,似曾相识,脑海浮现了利用random(0,1)产生0或1,从而组成二进制数,来完成random(a,b)的实现.但是细想以后,感觉有个问题在脑海中有点不明不白.

运行random(0,1)函数k次,使得2k>=(b-a+1),将得到[0,2k)的整数区间,如何将[0,2k)映射到[a,b]的整数区间,保证产生各整数的概率相等,同为1/(b-a+1).

1.当存在k使得2k=(b-a+1)时,只需将产生的二进制数与[a,b]整数一一对应,即可满足概率同为1/(b-a+1)的要求.

例如,random(3,6),k=2. 此时,对应关系可为00~3,01~4,10~5,11~6.产生的概率为1/4.

2.当不存在k使得2k=(b-a+1)时,产生[0,2k)区间整数的概率为1/2k,小于1/(b-a+1).[0,2k)如何映射到[a,b]整数区间.

思路一:扩大[0,2k)区间,使得2k可以被(b-a+1)整除,这样可以把[0,2k)分成N段时,每一段对应[a,b]里的一个整数.

但这个思路,是不可行的,因为不存在这样的k值.要么2k=(b-a+1),要么2k>(b-a+1)且不可被(b-a+1)整除.

思路二:参取截断映射,即 [0,2k) 的前部分映射到[a,b],这样虽然可以达到产生整数的概率相等,但不等于1/(b-a+1),还有如果产生[0,2k)后部分的值如何处理.

这个思路,是可行的,如果产生后部分的值,就继续调用自身,重新random.从结果输出分析,最终random(a,b)最终输出的只有[a,b]里的整数,而且每个整数的概率相等,因而其产生的概率值是1/(b-a+1).

具体的实现代码如下:

 

 

int random(int a,int b)
{
    int m = 1;
    int len = b - a + 1;
    int k = 0;
    //计算最小的正整数k,使2^k >= len
    while(m < len)
    {
        k++;
        m *= 2;
    }
    m = 0;
    for(int i = 0;i < k;i++)
    {
        m += random(0,1) * (1<<i);
    }
    if(m + 1 > len)        
    {
        return random(a,b);
    }
    else
    {
        return m + a;
    }
}


 

dd

http://www.cnblogs.com/dwdxdy/archive/2012/07/28/2613135.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值