三个勇士谁活到最后
在瓦尼亚的土地上,亚伦、鲍勃和查理为他们中哪一个是有史以来最伟大的拼图家而争论。为了一劳永逸地结束这场争论,他们同意决斗到底。亚伦是一个糟糕的射手,命中目标的概率只有1/3。鲍勃稍微好一点,命中目标的概率是1/2。查理是一名专业的射手,从不失误。命中意味着杀死,被击中的人退出决斗。为了弥补射击技术上的不公平,决定选手们轮流射击,先是亚伦,然后是鲍勃,然后是查理。循环会一直重复,直到有一个人站着。而那个人将作为有史以来最伟大的谜团而被人们铭记。
A.编写一个函数来模拟单个快照。它应该使用以下声明:无效射击(bool和targetAlive,double accuracy);这将通过生成一个介于0和1之间的随机数,模拟某人以给定的精度向TargetLive射击。如果随机数小于准确度,则会命中目标,并且应将TargetLive设置为false。
例如,如果Bob向Charlie开枪,这可以被调用为:
射击(Charlielive,0.5);
这里,charlieAlive是一个布尔变量,指示Charlie是否还活着。在进入步骤b之前,使用驱动程序测试您的功能。
B一个明显的策略是,每个人都要射向仍然活着的最准确的射手,因为这个射手是最致命的,并且有最好的反击机会。编写第二个名为startDuel的函数,该函数使用shot函数来使用此策略模拟整个决斗。它应该循环直到只剩下一个参赛者,根据射击的对象调用射击功能,并根据正确的目标和命中目标的概率调用射击功能。函数应该返回一个变量,指示谁赢得了决斗。
C在main函数中,在循环中调用startDuel函数1000次,记录每个参赛者获胜的次数。输出当每个人都使用最精确的射击策略时,每个参赛者获胜的概率。
D一个违反直觉的策略是Aaron故意错过他的第一枪。此后,每个人都会采用向活着的最准确的射手射击的策略。这一策略意味着Aaron肯定能活过第一轮,因为Bob和Charlie会互相射击。修改程序以适应此新策略,并输出每个参赛者的获胜概率。 1. 不知道答案,不知道写的对不对
2. 没有完全按照题目要求写
3. 没有看懂要求 D,我的理解是 Aaron 不参与第 0 轮射击
4. 作业要自己写
A ~ C
#include <iostream>
#include <random>
#include <ctime>
#include <string>
#include <vector>
struct human_t {
std::string name;
double accuracy;
};
std::default_random_engine re(std::time(NULL));
size_t shoot(double accuracy) {
std::uniform_real_distribution<double> urd(0, 1);
if(urd(re) < accuracy) return true;
return false;
}
size_t get_attack_target(const std::vector<human_t> &people, const std::vector<bool> &alive, size_t self) {
size_t max_accuracy = 0;
for(size_t i = 0; i < people.size(); ++i) {
if(i == self) continue;
if(!alive) continue;
if(people.accuracy < people.accuracy) max_accuracy = i;
}
return max_accuracy;
}
size_t get_winner(const std::vector<bool> &alive) {
size_t winner = 0;
for(size_t i = 0; i < alive.size(); ++i) {
if(alive && !alive) winner = i;
if(alive && alive && winner != i) return -1;
}
return winner;
}
size_t startDuel(const std::vector<human_t> &people) {
std::vector<bool> alive(people.size(), true);
size_t winner;
for(size_t i = 0; (winner = get_winner(alive)) == (size_t)-1; i = (i + 1) % people.size()) {
if(alive) alive = !shoot(people.accuracy);
}
return winner;
}
int main() {
std::vector<human_t> people = {
{"Aaron", 1.0 / 3},
{"Bob", 1.0 / 2},
{"Charlie", 1.0}
};
std::vector<size_t> winners(people.size());
for(size_t i = 0; i < 1000; ++i) ++winners;
for(size_t i = 0; i < people.size(); ++i) {
std::cout << people.name << ": " << winners / 1000.0 << std::endl;
}
return 0;
}
D
#include <iostream>
#include <random>
#include <ctime>
#include <string>
#include <vector>
struct human_t {
std::string name;
double accuracy;
};
std::default_random_engine re(std::time(NULL));
size_t shoot(double accuracy) {
std::uniform_real_distribution<double> urd(0, 1);
if(urd(re) < accuracy) return true;
return false;
}
size_t get_attack_target(const std::vector<human_t> &people, const std::vector<bool> &alive, size_t self) {
size_t max_accuracy = 0;
for(size_t i = 0; i < people.size(); ++i) {
if(i == self) continue;
if(!alive) continue;
if(people.accuracy < people.accuracy) max_accuracy = i;
}
return max_accuracy;
}
size_t get_winner(const std::vector<bool> &alive) {
size_t winner = 0;
for(size_t i = 0; i < alive.size(); ++i) {
if(alive && !alive) winner = i;
if(alive && alive && winner != i) return -1;
}
return winner;
}
size_t startDuel(const std::vector<human_t> &people) {
std::vector<bool> alive(people.size(), true);
size_t winner;
size_t count = 0;
for(size_t i = 0; (winner = get_winner(alive)) == (size_t)-1; i = (i + 1) % people.size()) {
if(count++ != 0) {
if(alive) alive = !shoot(people.accuracy);
}
}
return winner;
}
int main() {
std::vector<human_t> people = {
{"Aaron", 1.0 / 3},
{"Bob", 1.0 / 2},
{"Charlie", 1.0}
};
std::vector<size_t> winners(people.size());
for(size_t i = 0; i < 1000; ++i) ++winners;
for(size_t i = 0; i < people.size(); ++i) {
std::cout << people.name << ": " << winners / 1000.0 << std::endl;
}
return 0;
}
本帖最后由 jhq999 于 2021-10-10 17:22 编辑
#include "stdio.h"
#include "stdlib.h"
#include <time.h>
struct SHOOT
{
intname;
bool isAlive;
double prob;
doubleshootnum;
doublesezong;
double live;
};
void Shoot(bool & targetAlive,double accuracy);
int StartDuel(SHOOT *inshts,int shtnum);
void Probsort(SHOOT *inshts,int shtnum);
int main(int argv,char argc[])
{
SHOOT sht={0};
sht.name=0,sht.isAlive=1,sht.prob=1.0/3.0;
sht.name=1,sht.isAlive=1,sht.prob=1.0/2.0;
sht.name=2,sht.isAlive=1,sht.prob=1.0;
srand(unsigned int(time(NULL)));
for (int i = 0; i < 1000; i++)
{
sht.isAlive=1;
sht.isAlive=1;
sht.isAlive=1;
int l=StartDuel(sht,3);
//printf("\nLive is %d\n",l);
}
for (int i = 0; i < 3 ;i++)
{
if (sht.shootnum)
{
printf ("%d prob is %.2lf liveprob is %.2lf\n",sht.name,sht.sezong/sht.shootnum,sht.live/1000);
}
else
{
printf ("%d prob is %.2lf liveprob is %.2lf\n",sht.name,sht.prob,sht.live/1000);
}
}
return 0;
}
void Probsort(SHOOT *inshts,int shtnum)
{
bool flag=true;
SHOOT tmp={0};
for (int i = 0; i < shtnum; i++)
{
for (int j = i+1; j < shtnum; j++)
{
if (inshts.prob<inshts.prob)
{
tmp=inshts;
inshts=inshts;
inshts=tmp;
flag=false;
}
}
if (flag)
{
break;
}
}
}
int StartDuel(SHOOT *inshts,int shtnum)
{
bool isexit=0;
int i=0,j=0,live=-1,start=1;
while (true)
{
isexit=1;
for (i = start; i < shtnum; i++)
{
start=0;
if (inshts.isAlive)
{
for (j = shtnum-1; j>=0; j--)
{
if (inshts.isAlive&&i!=j)
{
inshts.shootnum++;
Shoot(inshts.isAlive,inshts.prob);
if (!inshts.isAlive)
{
inshts.sezong++;
live=i;
//printf("%d kill %d,",inshts.name,inshts.name);
if (inshts.shootnum)
{
inshts.prob=inshts.prob>inshts.sezong/inshts.shootnum?
inshts.prob:inshts.sezong/inshts.shootnum;
}
}
isexit=0;
break;
}
}
}
}
if (isexit)
{
break;
}
}
//Probsort(inshts,shtnum);
inshts.live++;
return inshts.name;
}
void Shoot(bool & targetAlive,double accuracy)
{
int i=0;
//for (; i < rand()%100; i++);
i=(rand()%100);
targetAlive=i>int(accuracy*100)?1:0;
}
页:
[1]