排球队员站位问题+回溯思想

这个题的题意如图所示:

一开始理解起来可能有点困难,但是多看两遍就可以了.......仔细看下题目的每一个要求,这个对解题有很大影响!

思路:这个题,不能全说是搜索,还含有模拟,但是确实少不了搜索这一过程!

这个题采用了回溯的思想,然后就是注意一下3.4号球员是不能在同一排的,而且3号在前排的话只能是在第四号位!其余的应该就没什么了,当然细节也是要注意的嘛!

因为只有一组结果,所以把结果也放出来吧!

代码如下:

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
int pos_can_stand[6][6];//表示队员i能否站在位置j,1表示能,0表示不能!
bool pos_can_use[6];//表示位置号是否可以使用,true表示没人,可以使用,false表示有人了不可以使用!
int num[6];//表示队员的最终站位!
void init()
{
    for(int i=0; i<6; i++)
        for(int j=0; j<6; j++)
            if(i==j)
                pos_can_stand[i][j]=0;
            else
                pos_can_stand[i][j]=1;//因为每一个队员的球衣号码都与他们的站位号不同!
    pos_can_stand[0][4] = 0;//1号队员不在后排
    pos_can_stand[0][5] = 0;//1号队员不在后排
    pos_can_stand[1][4] = 0;//2号队员不是二传手
    pos_can_stand[2][1] = 0;//3号队员不是二传手
    pos_can_stand[2][4] = 0;//3号队员不是二传手
    pos_can_stand[4][2] = 0;//5号队员不是副攻手
    pos_can_stand[4][5] = 0;//5号队员不是副攻手
    pos_can_stand[5][2] = 0;//6号队员不是副攻手
    pos_can_stand[5][0] = 0;//6号队员不能站后排
    pos_can_stand[5][4] = 0;//6号队员不能站后排
    for(int i=0; i<6; i++)
        num[i]=-1;//初始化!
    for(int i=0; i<6; i++)
        pos_can_use[i]=true;
}
void fun()
{
    int sum_num=0,pos;
    while(sum_num<6)
    {
        for(pos=0; pos<6;)
        {
            if(sum_num==3)//如果第四号队员
            {
                if(num[2]==3)//如果3号队员站到了4号位(即唯一的前排可能),则4号队员应站后排
                {
                    pos_can_stand[3][1]=0;
                    pos_can_stand[3][2]=0;
                    pos_can_stand[3][3]=0;
                }
                else//表明第三号队员是站在后排!也就是说第四号球员只能站在前排了!
                {
                    pos_can_stand[3][0]=0;
                    pos_can_stand[3][4]=0;
                    pos_can_stand[3][5]=0;
                }
            }
            else//如果回溯的话,需要对第四位队员进行恢复,否则会发生错误,因为它的站位限制不固定
            {
                for(int i=0; i<6; i++)
                    if(i!=3)
                        pos_can_stand[3][i]=1;
            }
            if(pos_can_stand[sum_num][pos]&&pos_can_use[pos])
            {
                //如果当前的pos位置是可以使用的并且队员是可以在这个位置上的话
                num[sum_num]=pos;//把pos这个位置给sum_num+1号队员来站!
                pos_can_use[pos]=false;//此位置已经有人了!
                sum_num++;
                break;//退出for循环!
            }
            else
                pos++;//不然寻找下一个位置!
            while(pos==6)//如果找完了所有得位置都没发现能够符合条件,那就回溯!
            {
                sum_num--;//回溯到上一个队员!
                pos=num[sum_num];
                pos_can_use[pos]=true;//此时由于需要重新给sum_num找位置,
                //所以需要把之前使用的位置标记为没人使用!
                num[sum_num]=-1;
                pos++;//然后找下一个位置!
            }
        }
    }
}
void print()
{
    for(int i=0; i<6; i++)
        printf("第[%d]位队员所站的位置是[ %d ]......\n",i+1,num[i]+1);
}
int main()
{
    init();
    fun();
    print();
    return 0;
}
时间: 2024-11-14 13:02:26

排球队员站位问题+回溯思想的相关文章

第六篇 回溯思想(待举例)

一: 思想 有时我们要得到问题的解,先从其中某一种情况进行试探,在试探过程中,一旦发现原来的选择是错误的,那么就退回一步重新选择, 然后继续向前试探,反复这样的过程直到求出问题的解. 二:场景 回溯思想是一个非常重要的思想,应用场景也是非常广泛. ①   “下棋”:  每一次走棋的位置都要考虑到是否是损人利己,如果是害人害己的走法就要回撤,找下一步损人利己的走法. ②   “迷宫”:  这种问题用试探法来解决相信我也不用向大家介绍了,其实迷宫问题抽象起来就是“对图的遍历问题“,当然对 图的遍历我

数据结构与算法学习之路:迷宫问题——回溯思想找出所有路径

今天小伙伴和我说之前写的那个迷宫问题有些问题,我就改了改,感觉之前写的东西思路也不清晰,也比较乱,就重新写了一篇--别在意哈- 一.迷宫问题描述: 给定一个迷宫,以及起点和终点,通过设计算法,找到一条可以到达终点的路径.解决以后,想办法找到最短路径和所有路径. 二.解决方法: 1.找到一条可达的路径并不难,只要设定方向,然后每个点都去找一个可以走的方向一直向可行方向走就是了. 2.找到最短路径.要找到最短路径,可以尝试广度优先算法--BFS.BFS找图中一点到另一点的最短路径还是很方便的(没有权

算法只回溯思想

1.概念 回溯算法实际上一个类似枚举的搜索尝试过程,主要是在搜索尝试过程中寻找问题的解,当发现已不满足求解条件时,就"回溯"返回,尝试别的路径. 回溯法是一种选优搜索法,按选优条件向前搜索,以达到目标.但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为"回溯点". 许多复杂的,规模较大的问题都可以使用回溯法,有"通用解题方法"的美称. 2.基本思想    在

ACM算法集锦

kurXX最小生成树 #include <iostream> #include <math.h> #include <algorithm> using namespace std; #define M 501 #define LIM 20000000 struct edg{ int u,v; int w; }all_e[M*M/2]; bool operator < (const edg &a,const edg &b){ return a.w&l

排球比赛计分程序功能说明书

编写目的让裁判和排球爱好者,赛事组织便于记录分数和查询赛事记录.目标不包括犯规判定.项目用户赛事组织和裁判以及广大排球爱好者.项目典型场景2016年里约奥运会女排决赛.专业术语插上进攻后排队员插到前排作二传,把球传给前排3个队员扣球的进攻形式.一般以1号位插上为多.插上进攻能保持前排3点进攻,充分利用球网的全长,有利于突破对方的防线.战术变化多,可以打出交叉.梯次.夹塞.立体进攻.双快一游动等战术进攻. 夹塞进攻一位扣球队员却二传手配合,佯扣短平快球,吸引对方拦网.另一位扣手突然插入两人之间扣球

排球计分规则程序说明书

需要完成的目标: 通过程序说明书,更好的更直观的了解排球计分规则.并且使比分程序化,更好的完成现代化进程. 用户: 喜欢排球的观众.裁判员.教练及运动员. 典型场景: 2016里约热内卢夏季奥运会女排总决赛中国女排对阵塞尔维亚女排. 专业术语: 反攻 排球运动四次的一种.指后排防起对方攻来之球以后所组织的反击,和在网上直接拦击对方各种进攻.是得分的主要手段.在比赛中出现次数最多,难度也最大.其过程包括:拦网.后排防守.调整二传和扣球等几个相互衔接的部分.其中拦网是第一道防线,后排防守是反攻的基础

排球计分程序功能说明书

目标: 帮助排球裁判计分,以减轻裁判的负担.并记录比赛计分的过程.目标不包括犯规的判定.详细的了解了比赛计分规则之后及用户需要所形成的汇总.通过这个文档能够明确以后项目的进度与规划,组织软件的开发与测试. 用户: 喜欢排球的观众.裁判员.教练及运动员. 典型场景: 2016里约热内卢夏季奥运会女排总决赛中国女排对阵塞尔维亚女排. 专业术语: 反攻 排球运动四次的一种.指后排防起对方攻来之球以后所组织的反击,和在网上直接拦击对方各种进攻.是得分的主要手段.在比赛中出现次数最多,难度也最大.其过程包

排球比赛计分规则功能说明书

1.1 编写目的 这份需求规格说明书是需求分析阶段的产物,在经过我们小组内的沟通之后,详细的了解了比赛计分规则之后及用户需要所形成的汇总.通过这个文档能够明确以后项目的进度与规划,组织软件的开发与测试. 1.2 项目背景 开发名称:排球比赛计分规则 项目提出者:老师 项目开发者:第二组全体成员 用户:喜欢排球的观众.裁判员.教练及运动员 实现该软件的计算机网络:学校机房 项目与其他软件:系统关系 1.3 专业术语解释 短平快 排球运动快球的一种.一般指二传手正面传出速度快.弧度平的球的同时,扣球

回溯法、数独与N阶可达问题(一)

回溯法是剪了枝的穷举,这是字面上的说法,不太好理解,不如讲解实例来的酸爽,于是引出了N阶可达问题: 有N个国家,每个国家有若干城市,小明要从中国(任意一个城市)出发,遍历所有国家(假设这个遍历顺序已经定了),最终到达美利坚(任意一个城市).而城市之间有可能不可达,只有小明尝试过才知道(就是后面的check()函数),求满足要求的一条路径? 从上面的表述中我们已经嗅到了浓浓的穷举屌丝气质——遍历所有组合,但是我们的回溯思想总是基于这样一个简单的事实:如果当前选择导致你走进了死胡同,那么这个选择一定