猴子选大王的问题

csszhz 2009-04-18 11:13:57
有1000只猴子,从0~999编号,之后手拉手排成一行。从第一个开始将奇数位置的猴子扔出去,之后剩下的猴子继续排成一排,重复上述操作,问最后剩下的猴子是几号?


...全文
472 点赞 收藏 19
写回复
19 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
qingronglu 2010-12-21
#include <stdio.h>
#include <malloc.h>

struct monkey{
int num;
struct monkey* next;
};
struct monkey* CreateLink(int n);
int KingOfMonkeys(struct monkey* head, int m);

struct monkey* CreateLink(int n)
{
int i=0;
struct monkey *head=NULL;
struct monkey *temp=NULL;
struct monkey *newNode=NULL;
for(i=0; i<n; i++)
{
if(head==NULL)
{
head=(struct monkey*)malloc(sizeof(struct monkey));
head->num=i+1;
head->next=head;
temp=head;
}
else
{
newNode=(struct monkey*)malloc(sizeof(struct monkey));
newNode->num=i+1;
temp->next=newNode;
newNode->next=head;
temp=newNode;
}
}
return head;
}

int KingOfMonkeys(struct monkey* head, int m)
{
int i=0;
struct monkey* temp = head;
for(i=1;temp->next!=temp;i++)
{
if(i%m==0)
{
if(head==temp)
{
while(temp!=head->next)
head=head->next;
}
head->next=temp->next;
free(temp);
temp=head->next;
}
else
{
head=temp;
temp=temp->next;
}
}
return temp->num;
}


void main()
{
int m, n, king;//定义m,n还有最后的大王
struct monkey *head=NULL;//初始化猴子大王的位子
printf("Please enter the number of the monkeys(m):\n");
scanf("%d",&m);//输入猴子数
printf("Please enter the value of n:\n");
scanf("%d",&n);//输入N
/*确保输入的m大于n的值且符合题意*/
if(m<n||m==n||m==0||n==0||m<0||n<0)
printf("Wrong enter!\n");
else
{
head=CreateLink(m);
king=KingOfMonkeys(head, n);
printf("The king of the monkeys is number: %d\n", king);
}
}
回复
SimonYeung 2009-04-20
约瑟夫环
回复
arlande 2009-04-19
import java.util.*;
class Monkey{
public static void main(String[] args){

ArrayList <Integer> arr = new ArrayList <Integer>(1000);

for (int i = 0; i < 1000; i++) {
arr.add(i);
}

while (arr.size() > 1) {

int count = 0;
for (int i = 0; i < arr.size(); i++) {
if (++count % 2 == 1) {
arr.set(i, -1);
}
}

for (int i = 0; i < arr.size(); i++) {
if (arr.get(i) == -1){
arr.remove(i);
}
}

}

System.out.println("最后剩下的猴子的编号为:" + arr.get(0));


}
}
count 应该放在while 循环内部。如上编程,最后为正解511
回复
Steve 2009-04-19
非要费尽模拟的话:

public class MonkeyKing
{
private static final int N = 1000;
public static void main(String[] args) {
int a [] = new int[N+1]; // a[0]表示存活的第一只猴子的位置,位置从1-1000, 输出时-1对应0-999
for (int i=0; i<=N; i++)
a[i] = i+1; //a[i]表示编号为i-1的猴子紧邻的后一个猴子位置

int num = N;
while (num>1) //num表示存活猴子数
{
int startPos = 0;

while (a[startPos]<N)
{
a[startPos] = a[a[startPos]]; //跳过一只猴子
startPos = a[startPos]; //向下移动两个位置
}

num = num / 2; //猴子数减半
}
System.out.println(a[0]-1); // 输出结果
}
}
回复
Steve 2009-04-19
[Quote=引用 14 楼 csszhz 的回复:]
不是这样说的,要是隔三个扔一个呢?要是隔五个扔一个呢?
话说这题能不能总结出一个数学函数出来f(x)=???
有没有人帮我用数组存储的方式写一个可运行的代码?
[/Quote]
隔三个扔一个?选几个大王呢.
回复
csszhz 2009-04-19
[Quote=引用 10 楼 runffer_yang 的回复:]
这题还用写程序吗?
就是求1-1000哪个数含有2的因数最多,因为2^10=1024, 所以2^9=512就是所求的解.
因为编号是0-999,所以答案就是511.

Java code
System.out.println(511);
[/Quote]
不是这样说的,要是隔三个扔一个呢?要是隔五个扔一个呢?
话说这题能不能总结出一个数学函数出来f(x)=???
有没有人帮我用数组存储的方式写一个可运行的代码?
回复
Steve 2009-04-19
[Quote=引用 11 楼 jinxfei 的回复:]
楼上的,511好像第二遍就会被干掉?
[/Quote]
编号从0开始,511是偶数位,最后才被干掉.
回复
csszhz 2009-04-19
6楼的代码不能直接用,照下面倒是编译通过了。
package hzxdw;
import java.util.ArrayList;
public class chooseKing {

public void run() {
ArrayList <Integer> arr = new ArrayList <Integer>(1000);

for (int i = 0; i < 1000; i++) {
arr.add(i);
}
int count = -1;
while (arr.size() > 1) {

for (int i = 0; i < arr.size(); i++) {
if (++count % 2 == 1) {
arr.set(i, -1);
}
}

for (int i = 0; i < arr.size(); i++) {
if (arr.get(i) == -1){
arr.remove(i);
}
}
}

System.out.println("最后剩下的猴子的编号为:" + arr.get(0));
}
}

测试类
package hzxdw;

public class Test {
public static void main(String[] args) {
chooseKing k=new chooseKing();
k.run();
}
}

照这样可以编译通过,但是代码我看不懂。
可不可以用数组存储猴子编号?
回复
jinxfei 2009-04-19
楼上的,511好像第二遍就会被干掉?
回复
Steve 2009-04-19
这题还用写程序吗?
就是求1-1000哪个数含有2的因数最多,因为2^10=1024, 所以2^9=512就是所求的解.
因为编号是0-999,所以答案就是511.

System.out.println(511);
回复
csszhz 2009-04-19
我试试,怎么和我的思路这么不同?
回复
ny_shaoer 2009-04-19
上面的是个方法,

用的时候写这个就OK了.
System.out.println( Arrays.toString( chooseKing( a ) )  );


回复
ny_shaoer 2009-04-19

public static int[] chooseKing( int a[] )
{
if ( a.length == 1 )
return a;

int[] b = new int[ a.length / 2 ];
int count = 0;

for ( int i = 0; i < a.length; i++ )
{
if ( i % 2 != 0 )
{
b[count] = a[i];
count++;
}
}
return chooseKing( b );
}

回复
zhongyucai 2009-04-19
public class Monkey{
public static void main(String[] args){
public void run() {
ArrayList <Integer> arr = new ArrayList <Integer>(1000);

for (int i = 0; i < 1000; i++) {
arr.add(i);
}
int count = -1;
while (arr.size() > 1) {

for (int i = 0; i < arr.size(); i++) {
if (++count % 2 == 1) {
arr.set(i, -1);
}
}

for (int i = 0; i < arr.size(); i++) {
if (arr.get(i) == -1){
arr.remove(i);
}
}
}

System.out.println("最后剩下的猴子的编号为:" + arr.get(0));
}

应该是这样的。。。
回复
itliyi 2009-04-19
楼上正解
回复
jinxfei 2009-04-19
[Quote=引用 1 楼 jinxfei 的回复:]
手工写的,仅做算法参考:

Java code
Vector v=new Vector();
for(int i=0;i<1000;i++){
v.add(new Integer(i));
}

while(v.size>1){
int index=0;
for(Iterator iter=v.iterator;iter.hasNext();){
if ((index % 2)==1){
iter.remove();
}
index++;
}
}

System.out.println(v.get(0));
[/Quote]

我少写了一个index++;
呵呵。
回复
效林少爷 2009-04-19
是需要写代码来实现吗?
用list
循环
可以实现
回复
yjfeng1986 2009-04-19

public void run() {
ArrayList <Integer> arr = new ArrayList <Integer>(1000);
// 初始编号1至1000
for (int i = 0; i < 1000; i++) {
arr.add(i);
}
int count = -1;// 计数值
while (arr.size() > 1) {//最后只剩下1只猴子
//编号为奇数时赋值为-1(做记号)
for (int i = 0; i < arr.size(); i++) {
if (++count % 2 == 1) {
arr.set(i, -1);
}
}
//将记号为-1的值从列表中删除
for (int i = 0; i < arr.size(); i++) {
if (arr.get(i) == -1){
arr.remove(i);
}
}
}
// 输出剩下结果
System.out.println("最后剩下的猴子的编号为:" + arr.get(0));
}

回复
jinxfei 2009-04-19
手工写的,仅做算法参考:

Vector v=new Vector();
for(int i=0;i<1000;i++){
v.add(new Integer(i));
}

while(v.size>1){
int index=0;
for(Iterator iter=v.iterator;iter.hasNext();){
if ((index % 2)==1){
iter.remove();
}
}
}

System.out.println(v.get(0));
回复
相关推荐
发帖
Eclipse
创建于2007-09-28

5.8w+

社区成员

Java Eclipse
申请成为版主
帖子事件
创建了帖子
2009-04-18 11:13
社区公告
暂无公告