UVa 1636 Headshot (条件概率)
题目
题目大意
首先在左轮手枪里随机装一些子弹, 然后扣了一枪, 发现没有子弹。你希望下一枪也没有子弹, 是应该直接再扣一枪(输出SHOOT
)呢, 还是随机转一下再扣(输出'ROTATE')? 如果两种策略下没有子弹的概率相等, 输出EQUAL
。
手枪里的子弹可以看成一个环形序列, 开枪一次后对准下一个位置。例如, 子弹序列为0011
时, 第一次开枪前一定在位置\(1\)或\(2\)(因为第一枪没有子弹), 因此开枪之后位于位置\(2\)或\(3\)。如果此时开枪, 有一半的概率没有子弹。序列长度为\([2, 100]\)
题解
直接扣一枪后会对准下一个位置, 若对应子串为00
则没有子弹, 若为01
则有子弹。设00
串的个数为\(a\), 00
串和01
串的总数为\(b\), 则直接扣一枪没有子弹的概率为\(\frac{a}{b}\)。
随机旋转可能转到任意一个位置, 则转一下到0
的几率是0
数(也就是\(b\))除以序列总长度\(n\), 所以转一下再扣一枪没有子弹的几率为\(\frac{b}{n}\)。
显然, 若\(\frac{a}{b} > \frac{b}{n}\)也就是\(an > b^2\)时, 直接扣一枪没有子弹几率大, 输出SHOOT
; 同理, \(an < b^2\)输出ROTATE
, \(an = b^2\)输出EQUAL
。
代码
#include <cstdio>
#include <string>
#include <iostream>
std::string str;
int n, a, b;
int main(int argc, char const *argv[]) {
while (getline(std::cin, str)) {
n = str.length();
str.push_back(str[0]);
a = b = 0;
for (register int i(0); i < n; ++i) {
if (str[i] == '0') {
if (str[i + 1] == '0') ++a;
++b;
}
}
puts(a * n == b * b ? "EQUAL" : (a * n > b * b ? "SHOOT" : "ROTATE"));
}
return 0;
}