DS实验题 击鼓传花
题目:

代码1(数组实现):
//
// main.cpp
// DS-击鼓传花
//
// Created by wasdns on 16/11/9.
// Copyright © 2016年 wasdns. All rights reserved.
//
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <string.h>
#include <string>
using namespace std;
int killman[1000]; //killer and alive man
int main()
{
int n, m;
cin >> n >> m;
memset(killman, 0, sizeof(killman));
int killt = 1; //死亡情况,如果killt=总人数,结束游戏
killman[1] = -1; //第一位发言差,根据题目要求首杀
int rcd = 1, turn = 1; //rcd记录存活者,turn为指针
int cnt = 0; //cnt计数器,一旦为m,杀掉此时指针指向者
while (1)
{
if (turn > n) { //指针越界
turn %= n;
}
if (killman[turn] == -1) { //此时指向的人已经死亡
turn++;
continue;
}
cnt++; //指向的人还活着,更新计数器
if (cnt == m) { //计数器计数为m,同时指针指向的人还活着
killman[turn] = -1; //杀死
killt++; //总死亡人数加一
rcd = turn; //rcd记录截止目前最后一位阵亡的同学
cnt = 0; //计数器置0
if (killt == n) break; //游戏结束
}
turn++; //游戏还没有结束,指针后移
}
cout << rcd << endl; //最后一位同学假死,存活
return 0;
}
结果:
代码2(指针实现):
//
// main2.cpp
// DS-击鼓传花
//
// Created by wasdns on 16/11/9.
// Copyright © 2016年 wasdns. All rights reserved.
//
#include <cstdio>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
struct killman {
int num;
killman *next;
};
/*
建立循环链表:
*/
killman* CreatCircle(int n) {
killman *k;
k = new killman;
k -> next = NULL;
k -> num = 1;
killman *p1, *p2;
p1 = p2 = k;
for (int i = 2; i <= n; i++)
{
p1 = new killman;
p1 -> next = NULL;
p1 -> num = i;
p2 -> next = p1;
p2 = p1;
}
p1 -> next = k;
return k;
}
/*
根据题目要求,找到开始节点的前一个节点。
目的是为了删除第一个节点。
*/
killman* FindKpre(killman *k)
{
killman *p;
p = k;
while (p -> next != k) {
p = p -> next;
}
return p;
}
/*
杀人游戏主体:
*/
int killgame(killman *k, int m)
{
int cnt = m; //计数器cnt,根据题目要求,初始置m
killman *p1, *p2; //p1 为指向当前节点的指针;
//p2 为指向前一个节点的指针。
p1 = k;
p2 = FindKpre(k); //找到开始节点的前一个节点,进行删除操作
while (1)
{
if (cnt == m) { //计数器达到阈值时,删除当前节点
p1 = p1 -> next;
p2 -> next = p1;
cnt = 1; //注意:删除之后,本质上进行了前移;
//计数器置1.
continue;
}
if (p2 -> next == p2) break; //当出现回环(loop)的时候:
//说明只剩下当前节点,游戏结束。
cnt++; //计数器尚未溢出,指针前移,更新计数器。
p2 -> next = p1;
p2 = p1;
p1 = p1 -> next;
}
return p1 -> num; //返回游戏的赢家
}
/*
Debug,输出环形链表:
*/
void KPrint(killman *k) {
killman *p;
p = k -> next;
while (p != k) {
cout << "p " << p -> num << endl;
p = p -> next;
}
}
int main()
{
int n, m;
cin >> n >> m;
killman *k;
k = CreatCircle(n);
//KPrint(k);
int rcd = 1;
rcd = killgame(k, m);
cout << rcd << endl;
return 0;
}
结果:
小结:
此题是经典的约瑟夫问题,采用ADT表,有两种实现方法:(1)指针实现 (2)数组实现。
需要注意的点是:
- 题目把第一个人直接出局
- 计数器和指针更新时的位置(更新指针之后马上更新计数器!)
- 循环结束条件
可以看到,使用环形链表的性能更优,但是实现相比数组而言更加复杂。
2016/11/9
DS实验题 击鼓传花的更多相关文章
- DS实验题 融合软泥怪-2 Heap实现
题目和STL实现:DS实验题 融合软泥怪-1 用堆实现优先队列 引言和堆的介绍摘自:Priority Queue(Heaps)--优先队列(堆) 引言: 优先队列是一个至少能够提供插入(Insert) ...
- DS实验题 Old_Driver UnionFindSet结构 指针实现邻接表存储
题目见前文:DS实验题 Old_Driver UnionFindSet结构 这里使用邻接表存储敌人之间的关系,邻接表用指针实现: // // main.cpp // Old_Driver3 // // ...
- 洛谷 P2529 [SHOI2001]击鼓传花 解题报告
P2529 [SHOI2001]击鼓传花 题意:求出\(n!\)末尾最后一位非0数字 数据范围:\(n<=10^{100}\) 我们从简单的开始考虑 1.显然,\(n!\)可以被这么表示 \(n ...
- FZU 1962 新击鼓传花游戏
新击鼓传花游戏 Time Limit: 1000ms Memory Limit: 32768KB This problem will be judged on FZU. Original ID: 19 ...
- 原生JS实现队结构及利用队列模拟‘击鼓传花’游戏
1. 前言 队列,是一种遵从先进先出(FIFO,First-In-First-Out)原则的有序集合.队列在尾部添加新元素,并从顶部移除元素,最新添加的元素必须排在队列的末尾. 2.功能说明 enqu ...
- 击鼓传花联想到了Java设计模式:责任链模式
目录 应用场景 简单示例 责任链模式 定义 意图 主要解决问题 何时使用 优缺点 击鼓传花的故事 应用场景 http web请求处理,请求过来后将经过转码.解析.参数封装.鉴权等一系列的处理(责任), ...
- DS实验题 Dijkstra算法
参考:Dijkstra算法 数据结构来到了图论这一章节,网络中的路由算法基本都和图论相关.于是在拿到DS的实验题的时候,决定看下久负盛名的Dijkstra算法. Dijkstra的经典应用是开放最短路 ...
- DS实验题 sights
算法与数据结构实验题 6.3 sights ★实验任务 美丽的小风姑娘打算去旅游散心,她走进了一座山,发现这座山有 n 个景点, 由于山路难修,所以施工队只修了最少条的路,来保证 n 个景点联通,娇弱 ...
- DS实验题 order
算法与数据结构 实验题 6.4 order ★实验任务 给出一棵二叉树的中序遍历和每个节点的父节点,求这棵二叉树的先序和后序遍历. ★数据输入 输入第一行为一个正整数n表示二叉树的节点数目,节点编号从 ...
随机推荐
- 修改iptables防火墙规则解决vsftp登录后不显示文件目录的问题
如果设置防火墙开端口可能只是常用的几个端口,这样很可能导vsftpd在被动模式时无法启动随机端口,从而造成客户端的FTP无法列出目录这样胡问题.解决方式很简单,给 vsftpd增加随机端口范围,然后把 ...
- linux tricks 之 bitmap分析.
------------------------------------------- 本文系作者原创, 欢迎大家转载! 转载请注明出处:netwalker.blog.chinaunix.net -- ...
- C与C++的细微区别——省略形式参数名
转自:http://www.cppblog.com/ownwaterloo/archive/2009/04/26/omit_parameter_name.html 一.C与C++的细微区别 在函数声明 ...
- RTP/RTCP/RTSP/SIP/SDP 关系(直接看总结)
RTP/RTCP/RTSP/SIP/SDP 关系 RTP(实时传输协议,传输层) Real-time Transport Protocol)是用于Internet上针对多媒体数据流的一种传输层协议 ...
- 【现代程序设计】homework-05
本次作业要求设计服务器和客户端,由于之前对网络编程是一窍不通,上上节课听宗学长讲述Tcp的时候心里想这个东西还真是高大上啊一点儿都听不懂,但是上个周末看了看C#网络编程的博客和书之后,发现这个东西入门 ...
- cocos2dx游戏开发——微信打飞机学习笔记(十)——碰撞检测的搭建
一.七说八说 大家都发现了= =,做了那么多,发现就是摆设,完全没有打飞机的感觉,没有实现碰撞的监测.比如说呢,子弹和敌机,玩家与敌机就是需要有碰撞检测的说,然后在这篇我想会很长很长的教 ...
- 织梦内页读取栏目banner图
<img src="{dede:field name='typeid' runphp='yes'} global $dsql; $typeid = @me; $query = 'SEL ...
- Hark的数据结构与算法练习之基数排序
算法说明 基数排序是基于计数排序的,所以看这个之前要先看一下计数排序对于理解基数排序是很有帮助的(发现计数和基数的音节几乎一致啊).这个我有写,请点击. OK,现在你肯定已经熟悉了计数排序,那么我就来 ...
- loadrunner中定义数组
loadrunner 中数组的定义 loadrunner 中数组的定义: lr_save_string("www.google.com","website_1" ...
- sprint1的个人总结及《构建之法》8、9、10章读后感
对sprint1的总结: 我们这次的sprint1做的挺差的,大家原来说好的分工都没有完成,也许是大家这段时间的大作业花了更多的时间,所以对这次团队任务的进度是拖慢了很多,但是团队已经认清了现阶段的问 ...

