zoukankan      html  css  js  c++  java
  • 2021.12大二上学期数据结构结课设计

    敢死队问题
    问题描述: 有 M 个敢死队员要炸掉敌人的一碉堡,谁都不想去,排长决定用轮回数数的办法来决 定哪个战士去执行任务。如果前一个战士没完成任务,则要再派一个战士上去。现给每个战 士编一个号,大家围坐成一圈,随便从某一个战士开始计数,当数到 N 时,对应的战士就 去执行任务,且此战士不再参加下一轮计数。如果此战士没完成任务,再从下一个战士开始 数数,被数到第 N 时,此战士接着去执行任务。以此类推,直到任务完成为止。 排长是不愿意去的,假设排长为 1 号,请你设计一程序,求出从第几号战士开始计数 才能让排长最后一个留下来而不去执行任务。
    基本要求: (1)输入队伍人数 M 和计数 N,输出排长指定的开始序号; (2)至少采用两种不同的数据结构的方法实现。

    感谢朗哥献祭“松籁响起之时”给我们小组抽到了最简单的课程设计题目hhhhhhhhhhhhhhhhhhhhh
    这题放到洛谷上也就普及+顶天了
    以下为思路及优化

    /*
     * 感谢丁老师提供的扑克牌举例演示
     * 需求分析:
     *		输入:总人数m,报数要求n
     *		输出:满足最后只剩排长一人的一次报数中第一个报数的人的编号
     *
     *		最后只剩排长一人即最后一个前去任务的人是排长
     *		即排长前去任务后洞中无人,则该次报数为符合题意的报数
     *		若一次派遣中,排长前去任务,此后洞中还有战士,则该次报数为不合题意的报数
     * 名词注解:
     *		一次派遣:指从1报到n,报到n的人出局。
     *		一次报数:指从第一次派遣直到排长报数后前去任务
     *
     * 第一次会议记录:11.22上午9时。明确所使用两种数据结构为顺序表、链式队列。聂乐恒负责顺序表实现,杨朗负责链式结构队列实现。各自确认了数据结构解决问题过程
     * 第二次会议记录:11.29上午9:30。就如何用队列解决问题产生意见分歧。yl思路为仅改变尾指针指向头指针位置,nlh思路为头指针和尾指针均正常向后移动(按照常规队列进行处理)以下为nlh思路部分代码
    Queue que;//定义队列
    a[i] = i+1;//a数组存的是队员编号
    int x;
    for(int i=0; i<m; ++i) {//一次报数中第一个报数的人,从0~m-1遍历
    	for(int j=0; j<m; ++j)//队员围成圈,从第一个报数的人开始向后延伸,队员入队
    		que.enqueue(a[(i+j)%n]);
    	do{//一次派遣
    		for(int k=0; k<n-1; ++k)//报数,报到1~n-1,不需前去任务
    			que.enqueue(que.dequeue());
    		x = que.dequeue();//报数,报到n,前去任务。x为前去任务的人的编号
    	}while(x!=0);//当排长前去任务时停止报数
    	if(que.empty())//排长前去任务后山洞内无人,是一次符合题意的报数
    		cout << i << "第一个报数" << endl;
    	while(!que.empty())//队列置空
    		que.dequeue();
    }
     *
     * 第一次优化:Length()函数求山洞内剩余人数为遍历求得,可在类内部定义变量length,每次派遣--length
     * 优势分析:支持每次派遣之间的n不同。实际意义在于,可能某次报数过程中,某战士为增大计算难度使每次派遣报数要求n不同。Get(x)支持x改变依然实现报数要求
     */
    

    yl链式队列代码

    点击此处查看代码LinkQueue.h
    #pragma once
    #include <iostream>
    #define nullptr NULL
    
    using namespace std;
    const int MaxSize = 100;
    
    template<typename DataType>
    struct Node
    {
    	DataType data = 0;												//此战士的编号
    	bool completed = false;											//默认每个战士都不能完成任务
    	Node<DataType>* next = nullptr;											
    };
    
    template<typename DataType>
    class LinkQueue
    {
    public:
    	LinkQueue();													//初始化空的链队列
    	~LinkQueue();													//释放链队列的存储空间
    	void EnQueue(DataType x, bool y);								//入队操作,将元素x和y入队
    	DataType DeQueue();												//出队操作,将指定的对头元素出队
    	int Length();													//返回当前队列的长度
    	bool Empty();													//判断链队列是否为空
    	bool LeaderSurvival();											//判断链队列中是否只剩下队长
    	void Work(int M, int N);										//求解问题
    private:
    	Node<DataType>* front, * rear;									//声明队头指针和队尾指针
    	int length = 0;													//记录当前队列的长度
    };
    
    template<typename DataType>
    LinkQueue<DataType>::LinkQueue()									//函数功能:初始化空的链队列
    {
    	Node<DataType> *s = nullptr;
    	s = new Node<DataType>;
    	s->next = nullptr;
    	front = rear = s;												//将队头指针和队尾指针都指向头结点s
    }
    
    template<typename DataType>
    LinkQueue<DataType>::~LinkQueue()									//函数功能:释放链队列的存储空间
    {
    	Node<DataType>* p = front;
    	while(!Empty())													//释放每一个结点的存储空间
    	{
    		front = front->next;
    		delete p;
    		p = front;													//工作指针后移
    	}
    }
    
    template<typename DataType>
    void LinkQueue<DataType>::EnQueue(DataType x, bool y)				//函数功能:将元素x和y入队
    {
    	Node<DataType>* s = nullptr;
    	s = new Node<DataType>;											//申请结点s
    	s->data = x;
    	s->completed = y;
    	s->next = nullptr;
    	rear->next = s;													//将结点s插入到队尾
    	rear = s;
    	++length;
    }
    
    template<typename DataType>
    DataType LinkQueue<DataType>::DeQueue()								//函数功能:将指定的队头元素出队
    {
    	DataType x;
    	bool y;
    	if(Empty()) throw "队列已经为空。";
    	Node<DataType>* p = front->next;								//暂存队头元素
    	x = p->data;
    	y = p->completed;
    	front->next = p->next;											//将队头元素所在结点摘链
    	if(p->next == nullptr) rear = front;							//出队前队列长度为1
    	delete p;
    	--length;
    	return x;
    }
    
    template<typename DataType>
    int LinkQueue<DataType>::Length()									//函数功能:返回当前队列的长度
    {
    	//cout << "front->data:" << front->data << "  **  " << "rear->data:" << rear->data << endl;
    	return length;
    }
    
    template<typename DataType>
    bool LinkQueue<DataType>::Empty()									//函数功能:判断队列是否为空
    {
    	return (length == 0);
    }
    
    template<typename DataType>
    bool LinkQueue<DataType>::LeaderSurvival()							//函数功能:判断队列中是否只剩下队长
    {
    	if ((length == 1) && (rear->data == 1))
    		return true;
    	return false;
    }
    
    template<typename DataType>
    void LinkQueue<DataType>::Work(int M, int N)						//函数功能:求解敢死队问题
    {
    	int a[MaxSize], x;
    	for (int i = 0; i < M; i++)                                     //讨论从0~10开始时,怎样才能使排长最后一个去执行任务
    	{
    		a[i] = i + 1;
    		for (int j = 0; j < M; j++)                                 //将M个敢死队员入队
    			EnQueue(a[(i + j) % M], false);
    		do                                                          //数数并派遣队头的敢死队员去执行任务
    		{
    			//cout << "Testing:" << i << "  **  Length:" << Queue.Length() << "  **  ";
    			for (int j = 0; j < N - 1; j++)
    				EnQueue(DeQueue(), false);
    			x = DeQueue();
    			if (LeaderSurvival())
    				cout << "排长可以指定的开始序号为:" << i + 1 << endl;
    		} while (x != 1);
    
    		while (Empty() != true)
    			DeQueue();
    	}
    }
    

    nlh顺序表

    点击此处查看代码SeqList.h
    #pragma once
    #include <iostream>
    using namespace std;
    const int Maxn = 101;
    
    int a[Maxn];
    class SeqList {
    public:
    	SeqList() {//置零
    		m = n = id = 0;
    		for (int i = 0; i < Maxn; ++i)
    			data[i] = 0;
    		length = 0;
    	}
    	void Set(int M, int N) {
    		m = M, n = N, id = 1;
    		for (int i = 1; i <= m; ++i)
    			data[i] = a[i] = i;
    		length = m;
    	}
    	void Reset(int a[], int begin) {//重置顺序表内容,本次报数从begin开始
    		for (int i = 1; i <= m; ++i)
    			data[i] = a[i];
    		id = begin;
    		length = m;
    	}
    	int Length() {//返回目前队伍长度
    		return length;
    	}
    	int Get(int x) {//查找从id号队员开始报数目前第x位的值
    		int count = 0, i = id-1;//i=id-1是因为下面while中第一句++i
    		while (count != x) {
    			++i;
    			if (i > m) i = 1;
    			if (data[i] != 0)
    				++count;
    		}
    //		cout << i << ' ';//输出该次派出执行任务的战士编号
    		data[i] = 0;
    		--length;
    		id = i;
    		return i;
    	}
    	void Work() {//问题求解,输出合法编号
    		for (int i = 1; i <= m; ++i) {
    			Reset(a, i);//重置数组,本次报数第一个报数的人编号为i
    			while(Get(n) != 1);//执行派遣直到排长去执行任务
    			if(Length() == 0)//排长去执行任务后洞中无人
    				cout << "从第 " << i << " 号战士开始计数能让排长最后一个留下来" << endl;
    		}
    	}
    private:
    	int data[Maxn];//data[i] = i,即编号对应编号
    	int m, n, id;//m为初始队伍人数,n为报数数字,id为下次开始报数的人的编号
    	int length;//剩余人数。*第一次优化
    };
    

    主文件

    点击此处查看代码main.cpp
    #include <iostream>
    #include "SeqList.h"
    #include "LinkQueue.h"
    using namespace std;
    
    int main(void) {
    	int m, n;
    	int op;
    	LinkQueue<int> Queue;
    	SeqList list;
    	do {
    		cout << endl << endl;
    		cout << "****************" << endl;
    		cout << "请输入指令" << endl;
    		cout << "0:停止程序" << endl;
    		cout << "1:链式队列解决问题" << endl;
    		cout << "2:顺序表解决问题" << endl;
    		cout << "****************" << endl << endl;
    		cin >> op;
    		if (op == 0) break;
    
    IN:		cout << "****************" << endl;
    		cout << "请输入队伍总人数m和报数要求n" << endl;
    		cout << "****************" << endl;
    		cin >> m >> n;
    		if (n < 0 || m < 0 || m > 101) {
    			cout << "输入数据有误!请重新输入" << endl;
    			goto IN;//重新输入
    		}
    		switch (op) {
    			case 1:
    				Queue.Work(m, n);
    				break;
    			case 2:
    				list.Set(m, n);
    				list.Work();
    				break;
    			case 0:
    				break;
    			default:
    				cout << "输入错误!请重新输入" << endl;
    		}
    	}while (op != 0);
    	return 0;
    }
    
  • 相关阅读:
    Cordova 配置文件
    Mac 配置gradle环境变量
    React实现TabBar切换,带动画效果
    【Mac】基于Android Studio搭建cordova开发环境
    Spring之IOC控制反转
    Spring Boot笔记三:Spring Boot之日志
    Spring Boot笔记二:Spring Boot配置文件
    java的代理机制
    Spring Boot笔记一:Spring Boot入门
    Spring Boot笔记
  • 原文地址:https://www.cnblogs.com/kuaileyongheng/p/15723569.html
Copyright © 2011-2022 走看看