鱼C论坛

 找回密码
 立即注册
查看: 1905|回复: 2

[已解决]三个勇士谁活到最后

[复制链接]
发表于 2021-10-9 21:13:14 | 显示全部楼层 |阅读模式
50鱼币
在瓦尼亚的土地上,亚伦、鲍勃和查理为他们中哪一个是有史以来最伟大的拼图家而争论。为了一劳永逸地结束这场争论,他们同意决斗到底。亚伦是一个糟糕的射手,命中目标的概率只有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会互相射击。修改程序以适应此新策略,并输出每个参赛者的获胜概率。
最佳答案
2021-10-9 21:13:15
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[i]) continue;
        if(people[max_accuracy].accuracy < people[i].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[i] && !alive[winner]) winner = i;
        if(alive[i] && alive[winner] && 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[i]) alive[get_attack_target(people, alive, i)] = !shoot(people[i].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[startDuel(people)];
    for(size_t i = 0; i < people.size(); ++i) {
        std::cout << people[i].name << ": " << winners[i] / 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[i]) continue;
        if(people[max_accuracy].accuracy < people[i].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[i] && !alive[winner]) winner = i;
        if(alive[i] && alive[winner] && 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[i]) alive[get_attack_target(people, alive, i)] = !shoot(people[i].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[startDuel(people)];
    for(size_t i = 0; i < people.size(); ++i) {
        std::cout << people[i].name << ": " << winners[i] / 1000.0 << std::endl;
    }
    return 0;
}
图片1.png
图片2.png

最佳答案

查看完整内容

1. 不知道答案,不知道写的对不对 2. 没有完全按照题目要求写 3. 没有看懂要求 D,我的理解是 Aaron 不参与第 0 轮射击 4. 作业要自己写 A ~ C D
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-10-9 21:13:15 | 显示全部楼层    本楼为最佳答案   
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[i]) continue;
        if(people[max_accuracy].accuracy < people[i].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[i] && !alive[winner]) winner = i;
        if(alive[i] && alive[winner] && 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[i]) alive[get_attack_target(people, alive, i)] = !shoot(people[i].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[startDuel(people)];
    for(size_t i = 0; i < people.size(); ++i) {
        std::cout << people[i].name << ": " << winners[i] / 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[i]) continue;
        if(people[max_accuracy].accuracy < people[i].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[i] && !alive[winner]) winner = i;
        if(alive[i] && alive[winner] && 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[i]) alive[get_attack_target(people, alive, i)] = !shoot(people[i].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[startDuel(people)];
    for(size_t i = 0; i < people.size(); ++i) {
        std::cout << people[i].name << ": " << winners[i] / 1000.0 << std::endl;
    }
    return 0;
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-10-10 17:21:17 | 显示全部楼层
本帖最后由 jhq999 于 2021-10-10 17:22 编辑
#include "stdio.h"
#include "stdlib.h"
#include <time.h>
struct SHOOT
{
        int  name;
        bool isAlive;
        double prob;
        double  shootnum;
        double  sezong;
        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[3]={0};
        sht[0].name=0,sht[0].isAlive=1,sht[0].prob=1.0/3.0;
        sht[1].name=1,sht[1].isAlive=1,sht[1].prob=1.0/2.0;
        sht[2].name=2,sht[2].isAlive=1,sht[2].prob=1.0;
        srand(unsigned int(time(NULL)));
        for (int i = 0; i < 1000; i++)
        {
                sht[0].isAlive=1;
                sht[1].isAlive=1;
                sht[2].isAlive=1;
                int l=StartDuel(sht,3);
                //printf("\nLive is %d\n",l);
        }
        for (int i = 0; i < 3 ;i++)
        {
                if (sht[i].shootnum)
                {

                
                        printf ("%d prob is %.2lf liveprob is %.2lf\n",sht[i].name,sht[i].sezong/sht[i].shootnum,sht[i].live/1000);
                }
                else
                {
                        printf ("%d prob is %.2lf liveprob is %.2lf\n",sht[i].name,sht[i].prob,sht[i].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[j].prob<inshts[i].prob)
                        {
                                tmp=inshts[i];
                                inshts[i]=inshts[j];
                                inshts[j]=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[i].isAlive)
                        {
                                for (j = shtnum-1; j>=0; j--)
                                {
                                        if (inshts[j].isAlive&&i!=j)
                                        {
                                                inshts[i].shootnum++;
                                                Shoot(inshts[j].isAlive,inshts[i].prob);
                                    
                                                if (!inshts[j].isAlive)
                                                {
                                                        inshts[i].sezong++;
                                                        live=i;
                                                        //printf("%d kill %d,",inshts[i].name,inshts[j].name);


                                                        if (inshts[j].shootnum)
                                                        {
                                                                inshts[j].prob=inshts[j].prob>inshts[j].sezong/inshts[j].shootnum?
                                                        inshts[j].prob:inshts[j].sezong/inshts[j].shootnum;
                                                        }
                                                }
                                                isexit=0;
                                                break;
                                        }
                                }
                        }

                }
                if (isexit)
                {
        
                        break;
                }
        }
        

        //Probsort(inshts,shtnum);
        inshts[live].live++;
        return inshts[live].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;
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-9-22 14:42

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表