题目:

代码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实验题 击鼓传花的更多相关文章

  1. DS实验题 融合软泥怪-2 Heap实现

    题目和STL实现:DS实验题 融合软泥怪-1 用堆实现优先队列 引言和堆的介绍摘自:Priority Queue(Heaps)--优先队列(堆) 引言: 优先队列是一个至少能够提供插入(Insert) ...

  2. DS实验题 Old_Driver UnionFindSet结构 指针实现邻接表存储

    题目见前文:DS实验题 Old_Driver UnionFindSet结构 这里使用邻接表存储敌人之间的关系,邻接表用指针实现: // // main.cpp // Old_Driver3 // // ...

  3. 洛谷 P2529 [SHOI2001]击鼓传花 解题报告

    P2529 [SHOI2001]击鼓传花 题意:求出\(n!\)末尾最后一位非0数字 数据范围:\(n<=10^{100}\) 我们从简单的开始考虑 1.显然,\(n!\)可以被这么表示 \(n ...

  4. FZU 1962 新击鼓传花游戏

    新击鼓传花游戏 Time Limit: 1000ms Memory Limit: 32768KB This problem will be judged on FZU. Original ID: 19 ...

  5. 原生JS实现队结构及利用队列模拟‘击鼓传花’游戏

    1. 前言 队列,是一种遵从先进先出(FIFO,First-In-First-Out)原则的有序集合.队列在尾部添加新元素,并从顶部移除元素,最新添加的元素必须排在队列的末尾. 2.功能说明 enqu ...

  6. 击鼓传花联想到了Java设计模式:责任链模式

    目录 应用场景 简单示例 责任链模式 定义 意图 主要解决问题 何时使用 优缺点 击鼓传花的故事 应用场景 http web请求处理,请求过来后将经过转码.解析.参数封装.鉴权等一系列的处理(责任), ...

  7. DS实验题 Dijkstra算法

    参考:Dijkstra算法 数据结构来到了图论这一章节,网络中的路由算法基本都和图论相关.于是在拿到DS的实验题的时候,决定看下久负盛名的Dijkstra算法. Dijkstra的经典应用是开放最短路 ...

  8. DS实验题 sights

    算法与数据结构实验题 6.3 sights ★实验任务 美丽的小风姑娘打算去旅游散心,她走进了一座山,发现这座山有 n 个景点, 由于山路难修,所以施工队只修了最少条的路,来保证 n 个景点联通,娇弱 ...

  9. DS实验题 order

    算法与数据结构 实验题 6.4 order ★实验任务 给出一棵二叉树的中序遍历和每个节点的父节点,求这棵二叉树的先序和后序遍历. ★数据输入 输入第一行为一个正整数n表示二叉树的节点数目,节点编号从 ...

随机推荐

  1. 一箭双雕打开Genesis

    打开记事本,将如下内容填入,保存时将后缀名改为bat @ ECHO 正在清理垃圾文件...del C:\tmp\*.* /f /q@ ECHO 清理完毕@ ECHO OFF@ ECHO.@ ECHO. ...

  2. MVC系统学习3—ModelBinder

    在ASP.NET MVC中,每个请求都被映射到一个Action方法,我们可以在action的方法中定义相应类型的参数,View中通过post.get方式提交的request参数,只要名称一致就会对应到 ...

  3. Java Hour 21 Weather

    有句名言,叫做10000小时成为某一个领域的专家.姑且不辩论这句话是否正确,让我们到达10000小时的时候再回头来看吧. 本文作者Java 现经验约为21 Hour,请各位不吝赐教. 继续心情不佳,那 ...

  4. JS中使用EL表达式

    转自:http://blog.csdn.net/monkeyking1987/article/details/17146951 分两种情况 1. JS代码在JSP页面中, 这可以直接使用EL表达式. ...

  5. uva 10246(最短路变形)

    题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=28972 思路:spfa求出每个点到其余顶点的最短路(最短路上的每个 ...

  6. JIT晚期(运行期)

    在部分的商用虚拟机(Sun HotSpot.IBM J9)中,Java程序最初是通过解释器(Interpreter)进行解释执行的,当虚拟机发现某个方法或代码块的运行特别频繁时,就会把这些代码认定为& ...

  7. mysql之对索引的操作

    1. 为什么使用索引? 数据库对象索引与书的目录非常类似,主要是为了提高从表中检索数据的速度.由于数据储存在数据库表中,所以索引是创建在数据库表对象之上的,由表中的一个字段或多个字段生成的键组成,这些 ...

  8. css构造文本

    1. 1. 文本缩进text-indent:值:值为数字,最常用的数值单位是px(像素),也可以直接是百分比!text-indent:100px;text-indent:10%;2. 文本对齐text ...

  9. NOIP 2002过河卒 Label:dp

    题目描述 如图,A 点有一个过河卒,需要走到目标 B 点.卒行走规则:可以向下.或者向右.同时在棋盘上的任一点有一个对方的马(如上图的C点),该马所在的点和所有跳跃一步可达的点称为对方马的控制点.例如 ...

  10. TYVJ P1090 母舰 Label:模拟,题目看清就好

    背景 广东汕头聿怀初中 Train#3 Problem 1 描述 在小A的星际大战游戏中,一艘强力的母舰往往决定了一场战争的胜负.一艘母舰的攻击力是普通的MA(Mobile Armor)无法比较的.对 ...