算法数据结构(一):猴子称王
【问题描述】
任务:一堆猴子都有编号,编号是1,2,3 ...m ,这群猴子(m个)按照 1--m的顺序围 坐一圈,从第1开始数,每数到第 N个,该猴子就要离开此圈,这样依次下来,直到圈中只 剩下最后一只猴子,则该猴子为大王。 输入数据:输入m,n。 m,n 为整数,n<m 输出形式:中文提示按照 m个猴子,数n 个数的方法,输出为大王的猴子是几号 ,建立 一个函数来实现此功能。
【其他要求】
(1)变量、函数命名符合规范。
(2)注释详细:每个变量都要求有注释说明用途;函数有注释说明功能,对参数、返回值也要以注释的形式说明用途;关键的语句段要求有注释解释。
(3)程序的层次清晰,可读性强。
(4)界面美观,交互方便。
一、数据结构说明
我采用的是动态数组数据结构,利用数组删除的方法每隔n个元素就进行一次向前覆盖操作,然后将计数向前推一位后继续进行间隔能个元素的删除操作,直到只剩下了一个元素后进行输出。
可视化界面我采用的是easyx图形化界面工具。
int *a = new int[m];//设置动态数组 for (int i = 0; i < m; i++) {//为动态数组赋值 a[i] = i + 1; } while (true) { if (m == 1)//只剩下一个元素的时候退出 break; for (int i = (num - 1 + n) % m; i < m - 1; i++) {//循环删除间隔元素 a[i] = a[i + 1];//向前覆盖 } num = (num - 1 + n) % m; m--; } return a[0];//返回猴子王元素
二、算法设计
1、猴子称王程序流程图
首先先构建开始界面,进入游戏后进行m和n的输入,在转换成数字之后利用m设置动态数组,并赋值。按照间隔n进行数组元素删除,即元素前移,直到只剩下一个元素的时候设置结果界面,输出结果,程序结束。如果出现了输入错误,就会进入错误界面,退出程序。
三、详细设计
#include <graphics.h>// 绘图库头文件,绘图语句需要 #include <conio.h>// 控制台输入输出头文件,getch()语句需要 #include<stdlib.h> #include <stdio.h> char s1[10], s2[10]; int a, b; void drawmenu(); void StartGame(); //核心算法 int monkeyking(int m, int n) { int num = 0,i; //构建动态数组 int *a = new int[m]; for (int i = 0; i < m; i++) { a[i] = i + 1; } //寻找并删除元素 while (true) { if (m == 1) break; for (int i = (num - 1 + n) % m; i < m - 1; i++) { a[i] = a[i + 1]; } num = (num - 1 + n) % m; m--; } return a[0]; } //输入错误 void wrong(){ MOUSEMSG m; initgraph(800, 600); setbkcolor(WHITE); cleardevice(); IMAGE img; loadimage(&img, _T("C:\\Users\\Hanson\\Desktop\\Project1\\timg.jpg")); putimage(0, 0, &img); setfillcolor(DARKGRAY); fillrectangle(200, 200, 600, 250); settextstyle(42, 0, "黑体");//设置文字格式 setbkmode(TRANSPARENT);// 去掉文字背景 outtextxy(210, 205, "输入错误,点击返回"); settextcolor(BLACK); settextstyle(75, 0, "楷体"); outtextxy(250, 0, "猴子称王"); while (1) { m = GetMouseMsg(); if (m.x >= 200 && m.x <= 600 && m.y > 200 && m.y <= 250) { if (m.uMsg == WM_LBUTTONDOWN) { StartGame(); } } } } //结果 void OverGame() { int c; char s[5]; c = monkeyking(a, b); MOUSEMSG m; initgraph(800, 600); setbkcolor(WHITE); cleardevice(); IMAGE img; loadimage(&img, _T("C:\\Users\\Hanson\\Desktop\\Project1\\timg.jpg")); putimage(0, 0, &img); setfillcolor(DARKGRAY); fillrectangle(200, 200, 600, 250); fillrectangle(200, 260, 395, 310); fillrectangle(405, 260, 600, 310); settextstyle(42, 0, "黑体");//设置文字格式 setbkmode(TRANSPARENT);// 去掉文字背景 itoa(c,s,10); outtextxy(230, 205, s); outtextxy(250, 205,"号猴子是猴子王"); outtextxy(250, 265, "退出"); outtextxy(455, 265, "返回"); settextcolor(BLACK); settextstyle(75, 0, "楷体"); outtextxy(250, 0, "猴子称王"); while (1) { m = GetMouseMsg(); if (m.x >= 200 && m.x <= 395 && m.y > 260 && m.y <= 310) { if (m.uMsg == WM_LBUTTONDOWN) { exit(0); } } if (m.x >= 405 && m.x <= 600 && m.y > 260 && m.y <= 310) { if (m.uMsg == WM_LBUTTONDOWN) { drawmenu(); } } } getchar(); } //开始游戏 void StartGame() { MOUSEMSG m; initgraph(800, 600); setbkcolor(WHITE); cleardevice(); IMAGE img; loadimage(&img, _T("C:\\Users\\Hanson\\Desktop\\Project1\\timg.jpg")); putimage(0, 0, &img); setfillcolor(DARKGRAY); // 左边1 高1 左边2 高2 fillrectangle(300,100,500,150); fillrectangle(300,200,500,250); fillrectangle(350, 300, 450, 350); settextstyle(42, 0, "黑体");//设置文字格式 setbkmode(TRANSPARENT);// 去掉文字背景 outtextxy(315, 105, "猴子数量"); outtextxy(315, 205, "间隔数量"); outtextxy(355, 305, "开始"); settextcolor(BLACK); settextstyle(75, 0, "楷体"); outtextxy(250, 0, "猴子称王"); while (1) { m = GetMouseMsg(); if (m.x >= 300 && m.x <= 500 && m.y > 100 && m.y <= 150) { if (m.uMsg == WM_LBUTTONDOWN) { InputBox(s1,10,"请输入猴子数量","猴子数量",0); a = atoi(s1); } } if (m.x >= 350 && m.x <= 450 && m.y > 200 && m.y <= 250) { if (m.uMsg == WM_LBUTTONDOWN) { InputBox(s2,10,"请输入间隔数量","间隔数量",0); b = atoi(s2); } } if (m.x >= 350 && m.x <= 450 && m.y > 300 && m.y <= 350) { if (m.uMsg == WM_LBUTTONDOWN) { if (b >= a) { wrong(); } else { OverGame(); } } } } } //初始界面 void drawmenu() { MOUSEMSG m; initgraph(800, 600); setbkcolor(WHITE); cleardevice(); IMAGE img; loadimage(&img, _T("C:\\Users\\Hanson\\Desktop\\Project1\\timg.jpg")); putimage(0, 0, &img); setfillcolor(DARKGRAY); fillrectangle(250, 200, 550,250); fillrectangle(250, 255, 550,305); settextstyle(42, 0, "黑体");//设置文字格式 setbkmode(TRANSPARENT);// 去掉文字背景 outtextxy(315, 205, "开始游戏"); outtextxy(315, 260, "退出游戏"); settextcolor(BLACK); settextstyle(75, 0, "楷体"); outtextxy(250, 0, "猴子称王"); while (1) { m = GetMouseMsg(); if (m.x >= 250 && m.x <= 550 && m.y > 200 && m.y <= 250) { if (m.uMsg == WM_LBUTTONDOWN) { StartGame(); } } if (m.x >= 250 && m.x <= 550 && m.y > 255 && m.y <= 305) { if (m.uMsg == WM_LBUTTONDOWN) { exit(0); } } } } int main() { drawmenu(); return 0; }
四、测试结果
五、来自2021年的评价
这是我2017年第一次在具体学会了一种语言后独自从设计并编写的一个小程序(过去有合作写过其他的)。
没有什么良好的代码格式,也没有一个良好的界面,甚至说报告写的也很不规范,但是却是令我印象深刻的一个项目,以至于我是熬夜写完了它。
我第一次,完全从无到有创造了属于自己的可视化程序,尽管很烂,但是我真的获得了编写代码的快乐。
思考,设计,编写,遇到调试问题,查资料,解决继续。就这么一路循环下来,我真的收获了很多。也为我以后的代码编写打下了一定的基础。