猴子选大王php
‘壹’ 初一数学题 猴子选大王
排第一位,就永远不可能报除了1以外的数,排第二位,就永远不可能报除了2以外的数。前面两个猴子不动,后面的猴子随着退出的越来越多总会挨到报3的机会。所以拍第一位的为猴王
‘贰’ 猴子选大王算法(快 得急)
我用java写了一个,也是给人帮忙啦,可以给兄台参考参考,有空的话,给你改个指针版出来
MonkeyNumber.java源程序如下:
package test;
import java.util.Scanner;
/**
* @author Administrator
*
* 有M只猴子围成一圈,每只各一个从1到M中的编号,
* 打算从中选出一个大王;经过协商,决定出选大王的规则:从第一个开始循环报数,
* 数到N的猴子出圈,最后剩下来的就是大王。
* 要求:从键盘输入M、N,编程输出猴子出列的次序并计算哪一个编号的猴子成为大王(用数组实现)。
* 要求程序完整,并且验证过,
*
*/
public class MonkeyNumber {
/**
* 出圈
* <b>方法描述</b>:第outNo号出圈 <p>
* <b>方法流程</b>:
* <p>
* @param monkey
* @param n
* @return outNo 出圈的索引号
*/
private static int getOut(int[] monkey,int n){
int outNo = -1;
int intValidVoters = getVotersNumber(monkey);
for(int i=0; i<monkey.length; i++){
if(intValidVoters > n){
if(monkey[i]==n%intValidVoters){
outNo = i+1;
monkey[i]=-1;// 去除该位置的值
System.out.print("--编号为["+outNo+"]的猴子出圈!--");
return outNo;
}
}
else if(intValidVoters < n){
if(monkey[i]==(n%intValidVoters==0?intValidVoters:n%intValidVoters)){
outNo = i+1;
monkey[i]=-1;// 去除该位置的值
System.out.print("--编号为["+outNo+"]的猴子出圈!--");
return outNo;
}
}
else if(intValidVoters==n){
if(monkey[i]==n){
outNo = i+1;
monkey[i]=-1;// 去除该位置的值
System.out.print("--编号为["+outNo+"]的猴子出圈!--");
return outNo;
}
}
}
return outNo;
}
/**
* 重新初始化数组
* <b>方法描述</b>:对输入的数组重新进行赋初值 <p>
* <b>方法流程</b>:
* <p>
* @param monkey
* @param startPos 从startPos位置开始赋初值,startPos索引的数组,其值置为1
*/
private static void reAssign(int[] monkey, int startPos){
int count = 0;
//数组中大于等于位置startPos的有效值的个数
int behindCount = getVotersNumber(monkey, startPos);
//对号码重新初始化
for(int i=0;i<monkey.length; i++){
int differenceValue = i-startPos+1;
if(monkey[i] != -1){
if(differenceValue < 0){
monkey[i]= ++behindCount;
}
else if(differenceValue >= 0){
monkey[i]= ++count;
}
}
}
}
/**
* <b>方法描述</b>:取得当前有效选民数 <p>
* <b>方法流程</b>:
* <p>
* @param monkey
* @return
*/
private static int getVotersNumber(int[] monkey){
int count = 0;
//计算目前多少个号码有效
for(int i=0;i<monkey.length; i++){
if(monkey[i] != -1){
count++;
}
}
System.out.print("当前有["+count+"]只猴子参加选举!");
return count;
}
/**
* <b>方法描述</b>:取得大于等于位置startPos的有效选民数 <p>
* <b>方法流程</b>:
* <p>
* @param monkey
* @return
*/
private static int getVotersNumber(int[] monkey,int startPos){
int count = 0;
//计算目前多少个号码有效
for(int i=startPos;i<monkey.length; i++){
if(monkey[i] != -1){
count++;
}
}
return count;
}
/**
* <b>方法描述</b>:主程序 <p>
* <b>方法流程</b>:测试
* <p>
* @param args
*/
public static void main(String[] args){
System.out.println("Input:M N ");
Scanner scanner = new Scanner(System.in);
String strM = scanner.next();
String strN = scanner.next();
while (strM == null || !strM.matches("[0-9]+")){
System.out.println("输入错误,您输入的第一个参数不是数字,请再次输入:");
scanner = new Scanner(System.in);
strM = scanner.next();
}
while (strN == null || !strN.matches("[0-9]+")){
System.out.println("输入错误,您输入的第二个参数不是数字,请再次输入:");
scanner = new Scanner(System.in);
strN = scanner.next();
}
int m = Integer.parseInt(strM);
int n = Integer.parseInt(strN);
System.out.println("当前有::["+m+"]只猴子"+",即将报的数是::["+n+"]");
int monkey[] = new int[m];
//赋初值
for(int i=0; i<m; i++){
monkey[i]=i+1;
}
for(int i=0; i<m-1; i++){
//出圈
int outNum = getOut(monkey,n);
int startPos = -1;
if(outNum==m){
startPos = 0;
}
else{
startPos = outNum;
}
//再次循环赋初值
reAssign(monkey,startPos);
System.out.println();
}
for(int i=0; i<m; i++){
if(monkey[i]!=-1){
System.out.println("Voting Success!!!编号为["+(i+1)+"]的猴子成为大王!");
}
}
}
}
‘叁’ 数据结构猴子选大王问题
#include <stdio.h>
#include <stdlib.h>
#define n 19
#define m 4
typedef struct monkey
{
int num;
struct monkey *next;
} Monkey,*LINK;
void main()
{
LINK p,head,p2;
int i;
head=p=p2=(LINK)malloc(sizeof(Monkey));//三个指针指向同一块内存
for(i=1;i<n;i++)
{
p=(LINK)malloc(sizeof(Monkey));
p2->next=p;
p2=p;
}
p2->next=head;//把链表的首尾相连
p=head;//p指向了第一个结点
printf("对猴子进行编号!\n");
for(i=1;i<=n;i++)
{
p->num=i;//从第一个结点到最后一个结点依次给猴子编号
printf("%d号猴子:%d\n",p->num,p->num);
p=p->next;
}//循环结束,p指向了最后一个结点
i=0;
p=head;//再把p指向第一个结点
while(1)
{
i++;
printf("%d号猴子报:%d\n",p->num,i);
if(p->next==p)
break;//此为while循环的出口
if(i==m)//if语句中是删除结点的过程
{
i=0;
printf("%d号猴被淘汰\n",p->num);
printf("\n");
p2->next=p->next;//在此删除结点p
p=p2->next;//p指向它的下一个结点
continue;
}
else
{
if(i==m-1)
p2=p;//保存将要退出结点的前一个结点(存到p2中)
p=p->next;
}
}
printf("胜出:%d",p->num);//最后剩下的结点就是获胜的结点
}
这个程序其实就是形成了一个有19个结点的循环链表,当碰到m的时候,用这两句话p2->next=head;p=head删除当前的结点,然后再继续判断。
‘肆’ 猴子选大王:
有M只猴子围成一圈,每只各一个从1到M中的编号,打算从中选出一个大王;经过协商,决定出选大王的规则:从第一个开始循环报数,数到N的猴子出圈,最后剩下来的就是大王。要求:从键盘输入M、N,编程计算哪一个编号的猴子成为大王
#i nclude<iostream.h>
int choose(int num,int del)
{
int i;
int a[100];
for(i=0;i<num;i++)
a[i]=1; //猴子状态初始化,为1表示可能被选上,为0表明没希望了;
int sum=0, //循环记数;
countOne=num; //累积记数初始化,大于1表明还有大王候选人;
while(countOne>1)
{
countOne=0;
for(i=0;i<num;i++)
{
sum+=a[i];
if(sum==del)
sum=a[i]=0; //淘汰倒霉猴子;
countOne+=a[i];
}
}
for(i=0;i<num;i++)
if(a[i]!=0)
return i; //找到幸运猴子编号(从0开始的);
}
void main()
{
int num,del;
cout<<"请输入猴子总数和淘汰数:";
cin>>num>>del;
cout<<"第"<<choose(num,del)+1<<"个猴子为王!"<<endl;
}
‘伍’ 新的 猴子选大王 代码 题目:猴子选大王 功能:设编号为1,2,3,……,n的n(n>0)个猴子按顺时针方向围坐
#include<iostream.h>
int choose(int num,int del)
{
int i;
int a[100];
for(i=0;i<num;i++)
a[i]=1; //猴子状态初始化,为1表示可能被选上,为0表明没希望了;
int sum=0, //循环记数;
countOne=num; //累积记数初始化,大于1表明还有大王候选人;
while(countOne>1)
{
countOne=0;
for(i=0;i<num;i++)
{
sum+=a[i];
if(sum==del)
sum=a[i]=0; //淘汰倒霉猴子;
countOne+=a[i];
}
}
for(i=0;i<num;i++)
if(a[i]!=0)
return i; //找到幸运猴子编号(从0开始的);
}
void main()
{
int num,del;
cout<<"请输入猴子总数和淘汰数:";
cin>>num>>del;
cout<<"第"<<choose(num,del)+1<<"个猴子为王!"<<endl;
}
‘陆’ 猴子选大王算法
我改好了 ~~~~~
顺序表和单链表两种方法都写好了
注释写得很清楚 相信你能看懂 有问题问我
你先运行就知道了
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 100
typedef struct Node
{
int data;//存储猴子编号
struct Node *next;
}*List;
/* 用链表来得出大王的序号 */
int LinkedList(int num_monkey,int number);
/* 用顺序表来得出大王的序号 */
int SequenceList(int num_monkey,int number);
/* 创建循环单链表 */
List CreateList(int n);
void main()
{
int m, n, way, king;
printf("请输入猴子个数:");
scanf("%d", &n);
printf("请输入要报的数:");
scanf("%d", &m);
while (1)
{
printf("\n请选择解决问题的方法:\n");
printf("1.单链表\n");
printf("2.顺序表\n");
scanf("%d", &way);
if (way == 1)
{
king = LinkedList(n,m);
break;
}
else if (way == 2)
{
king = SequenceList(n,m);
break;
}
else
{
printf("输入不合法!\n");
}
}
printf("%d号猴子是大王\n", king);
}
/* 创建循环单链表 */
List CreateList(int n)
{
int i;
List head, p;
head = (List)malloc(sizeof(struct Node));
head->next = head;
for (i = 1; i < n; ++i)
{
p = (List)malloc(sizeof(struct Node));
p->next = head->next;
head->next = p;
}
p = head;
for (i = 0; i < n; ++i)
{
p->data = i+1;
p = p->next;
}
return head;
}
/* 用链表来得出大王的序号 */
int LinkedList(int num_monkey,int number)
{
int i,j;
List head = CreateList(num_monkey);
List tail = head;//用来存储最后一个节点的地址
List out,p;//out指向要淘汰的节点,p指向其前一个节点
/* 让tail指向最后一个节点 */
for (i = 1; i < num_monkey; i++)
{
tail = tail->next;
}
/* 淘汰的猴子个数比总个数少1,报数一轮就淘汰一个猴子,所以需要报数的轮数比
猴子总个数少1*/
for( i = 1; i < num_monkey; i++ )
{
p = tail;
/* 让p指向要淘汰的猴子的前一个 */
for ( j = 1; j < number; j++ )
{
p = p->next;
}
out = p->next;
/* 如果最后一个猴子被淘汰就更新尾节点 */
if (out == tail)
{
tail = p;
}
p->next = out->next;
printf("猴子%d淘汰\n", out->data);
free(out);//删除被淘汰猴子的节点
}
return p->data;
}
/* 用顺序表来得出大王的序号 */
int SequenceList(int num_monkey,int number)
{
/* 用来表示个猴子的信息,如果猴子出局就存储0,否则存储1。第一个元素不使用 */
int monkey[MAXSIZE];
/* 用来表示出局的猴子的序号 */
int out = 1;
/* 用来表示当前猴子的个数 */
int num_now = num_monkey;
int i,j;
for (i = 0; i < num_monkey+1; i++)
{ /* 开始将每个元素置1 */
monkey[i] = 1;
}
/* 报数次数比猴子个数少一 */
for (i = 1; i < num_monkey; i++)
{
out = 1;
/* 报数整个过程 */
for (j = 0; j < number; j++)
{
/* 如果序号数大于猴子个数,表示循环了一圈,那么去掉那个圈数 */
if (out > num_monkey)
out -= num_monkey;
/* 之前已经出局的猴子不参加报数 */
while(monkey[out] == 0)
{
out ++;
/* 如果序号数大于猴子个数,表示循环了一圈,那么去掉那个圈数 */
if (out > num_monkey)
out -= num_monkey;
}
out++;
}
out--;//报完数后out应该是被淘汰的猴子的下一个,所以要向前移动
monkey[out] = 0;
printf("猴子%d淘汰\n",out);
}
while(monkey[out] == 0)
{
out ++;
/* 如果序号数大于猴子个数,表示循环了一圈,那么去掉那个圈数 */
if (out > num_monkey)
out -= num_monkey;
}
return out;
}
‘柒’ 猴子选大王 课程设计
任务:一堆猴子都有编号,编号是1,2,3 ...m ,这群猴子(m个)按照1-m的顺序围坐一圈,从第1开始数,每数到第N个,该猴子就要离开此圈,这样依次下来,直到圈中只剩下最后一只猴子,则该猴子为大王。
要求:输入数据:输入m,n ,m,n 为整数,n<m
输出形式:提示按照m个猴子,数n 个数的方法,输出为大王的猴子是几号 ,建立一个函数来实现此功能。
#include<stdio.h>
#include<stdlib.h>
typedef struct line
{
int data;
struct line *link;
}cycle;
int count=0;
cycle * creat(int n)
{
cycle * h,*p,*q;
int i;
h=p=(cycle *)malloc(sizeof(cycle));
h->data=1;
for(i=2;i<=n;i++)
{
q=(cycle *)malloc(sizeof(cycle));
q->data=i;
p->link=q;
p=p->link;
}
p->link=h;
return h;
}
cycle * king(cycle * head,int n,int m)
{
int i;
while(count<=n-1)
{
for(i=1;i<m-1;i++)
head=head->link;
head->link=head->link->link;
head=head->link;
count++;
}
return(head);
}
main()
{
int n,m;
cycle *head,*last;
printf("\n\nplease input the monkey number and out number:\n\n");
scanf("%d%d",&n,&m);
head=creat(n);
last=king(head,n,m);
printf("\n\nthe number of the fortunate one is:\n\n ");
printf("%d",last->data);
printf("\n\n");
system("pause");
}
是啊,一楼的说的对啊,这个程序并不难啊。你完全可以自己写啊。要好好学,不可以辜负了父母对我们的期望啊!
‘捌’ php猴子选大王的问题,谁能看看这个递归公式的由来,看起来很简单,但是不理解
这应该是一个约瑟夫环算法,你可以查查相关文章
‘玖’ 数据结构课程设计题目:猴子选大王问题
一:实验内容:
M只猴子要选大王,选举办法如下:所有猴子按1,2……n编号围成一圈,从第一号开始顺序1,2……m,凡是报m号的退出圈外,如此循环报数直到圈内只剩一只猴子时这只猴子就是大王。
二:实验要求:
利用单向循环链表模拟此过程,输出选出的大王编号。
三:程序的设计思想:
(1) 问题分析:“猴子选大王”问题是约瑟夫环问题的一个特例。由于本题目的数据元素个数不可知,所以可使用链表来动态的分配内存空间。而该问题又是一个不断的循环问题所以用循环链表来实现。
(2) 总体设计:首先生成一个空链表,并给n个结点分配空间,让单链表的表尾指针指向头结点则生成一个带有n个结点的循环单链表。再给每只猴子建立顺序的编号。现从第一个结点开始报数,依次顺序查找出报数为m的待出列的结点(猴子)通过q->next=p->next删除该结点后继续运行否则让q成为p的前驱指针。最后当p->next==p时停止运行,得到p所指向的结点即为猴子选出大王的编号。
四、源程序
#include <stdio.h>
#include <stdlib.h>
/* 定义链表节点类型 */
typedef struct node
{
int data;
struct node *next;
}linklist;
int main()
{
int i, n, k, m, total;
linklist *head, *p, *s, *q;
/* 读入问题条件 */
printf("Please enter the number of monkeys:");
scanf("%d", &n);
printf("Please enter from the monkeys began to count off the first of several:");
scanf("%d", &k);
printf("Please enter the number out:");
scanf("%d", &m);
/* 创建循环链表,头节点也存信息 */
head = (linklist*) malloc(sizeof(linklist));
p = head;
p->data = 1;
p->next = p;
/* 初始化循环链表 */
for (i = 2; i <= n; i++)
{
s = (linklist*) malloc(sizeof(linklist));
s->data = i;
s->next = p->next;
p->next = s;
p = p->next;
}
/* 找到第 k 个节点 */
p = head;
for (i = 1; i < k; i++)
{
p = p->next;
}
/* 保存节点总数 */
total = n;
printf("\nOut of sequence:");
q = head;
/* 只剩一个节点时停止循环 */
while (total != 1)
{
/* 报数过程,p指向要删除的节点 */
for (i = 1; i < m; i++)
{
p = p->next;
}
/* 打印要删除的节点序号 */
printf("[%d] ", p->data);
/* q 指向 p 节点的前驱 */
while (q->next != p)
{
q = q->next;
}
/* 删除 p 节点 */
q->next = p->next;
/* 保存被删除节点指针 */
s = p;
/* p 指向被删除节点的后继 */
p = p->next;
/* 释放被删除的节点 */
free(s);
/* 节点个数减一 */
total--;
}
/* 打印最后剩下的节点序号 */
printf("\n\n King of the Monkey is the No. [%d] \n\n", p->data);
free(p);
system("pause");
return 0;
}