面试中遇到的一些面试题记录之。
1)玩家和电脑对战猜数。双方各随机一个数,根据它们的和及各自奇偶,大小判断。根据规则总结即大者为胜,要求电脑胜率为70%,不让玩家看出电脑作弊。
当时一开始想的伪码为:
seed(time)
x = 0 //player
y = 0 //computer
r = random(100)
x = random(100)
y = random(100)
if(r < 70)
if( x > y)
swap(x, y)
感觉不妥。
1) 调用了3次random();
2) 当时无法判断每隔2次r之间的关联性是否很大。因为伪随机数的问题,如果用相邻的random()调用作为相关判断条件,概率出入会相当大。记忆如下:
function testrandom()
math.randomseed(os.time())
local x, y, z, w = 0, 0, 0, 0
for i = 0, 1000000 do
--r = math.random(100)
if(math.random(100) <=10) then
x = x + 1
end
if(10 < math.random(100) and math.random(100) <= 30) then
y = y + 1
end
if( 30 < math.random(100) and math.random(100) <= 60) then
z = z + 1
end
if(60 < math.random(100)) then
w = w + 1
end
end
print(x/100000, y/200000, z/300000, w/400000)
end
结果为:1.00166 1.34781 1.39648 1.0024525。说明整个随机序列中的以每一个相同长度的子序列为单位,其相关性很强,不能保证随机性。必须单个判断。
伪码这里虽然没用x,y做相应的判断,但r为在随机序列中每隔2个数取出一个组成的序列。那这种情况是否足够随机,惘然!回来后做实验,结果却通过测试,白操心。
多调用2次的问题,没有解决。能否根据r的值给出随机x,y值,效率上应该只用加减法和移位。移位是马后炮,当时没想到。根据一个r计算x,y值,使用一个hash函数,但是这样的话,固定的r值对应固定的x,y,又不满足不让玩家看出电脑作弊这一条件,似乎至少要再多计算一次random的值。