老谭<>书上的一个习题

78815 2003-12-01 04:41:32
有n个人围成一圈,顺序排号,从第一个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来第几号的那位。(用指针处理)


刚刚学习C语言,想了些时候,没什么思路,请大家提供一下,

...全文
96 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
lncd 2003-12-02
  • 打赏
  • 举报
回复
我的程序算出第91个人最后留下来,对否?
程序如下:

#include <stdio.h>
#include <stdlib.h>

void init(int *Ren,int RenShu)
{
int i;
for (i=0;i<RenShu;i++)
{
*(Ren+i)=1;
}
}


void main()
{
//////////////////
int i=0;
int j=0;
int *Ren;
int RenShu=100;
int JiShu=0;
/////////////////////
Ren=(int *)malloc(RenShu*sizeof(int));
init(Ren,RenShu);
while (1)
{
if (i==RenShu) i=0;
if (*(Ren+i)==1)
{
if (++JiShu % 3==0)
{
*(Ren+i)=0;
j++;
if (j==RenShu-1) break;
}
}
i++;
}
for (i=0;i<RenShu;i++)
{
printf("Ren[%d]=%d,",i,*(Ren+i));
}
free(Ren);
//printf("pai[%d]=%d,",j,pai[j]);
}
deermanlr 2003-12-02
  • 打赏
  • 举报
回复
用循环队列很简单
yuxh312 2003-12-02
  • 打赏
  • 举报
回复
反正链表里边是每个节点都用指针移动的
yuxh312 2003-12-02
  • 打赏
  • 举报
回复
我给你c的吧,其实很简单的啊,就是约瑟夫问题(猴子选大王的问题),用链表解决的,任意个元素,任意号码(小于总数)开始删除,输出了每个被删除的号码
输入的时候用逗号间隔,前面的是总数,后面的是循环因子
/*
*The monkey king problem
*By yuxh312
*
*/#include<stdio.h>
#include<stdlib.h>
typedef int DataType;

typedef struct node
{
DataType data;
struct node *next;
}Node;

void SetNode(Node *front)/*set empty linklist*/
{
front->next=NULL;
}

Node *NextNode(Node *ptr)/*get next pointer*/
{
return(ptr->next);
}

void InsertAfter(Node *ptr,DataType item)
{
Node *q;
q=(Node*)malloc(sizeof(Node));
if(q==NULL)
{
printf("Error--Overflow");
exit(1);
}
q->data=item;
q->next=ptr->next;
ptr->next=q;
}


void DeleteAfter(Node *ptr)
{
Node *q;
q=ptr->next;
if(q!=NULL)
{
ptr->next=q->next;
free(q);
}
}

void Selete(int n,int m)
{
int i,j;
Node front,*pre,*ptr;
SetNode(&front); /*use linklist struct script 'n' nummber monkeys*/
ptr=&front;
for(i=1;i<=n;i++)
{
InsertAfter(ptr,i);
ptr=NextNode(ptr);
}
pre=&front; /*let pointers indicate head node and start node*/
ptr=NextNode(pre);
for(i=1;i<=n-1;i++)
{
for(j=1;j<=m-1;j++) /*pointers step 'm-1' locations ,during this ,consider the linklist*/
{ /* as a circle ,if pointer face tail,that is 'ptr=NULL',*/
pre=ptr;
ptr=NextNode(ptr); /*let 'pre' indicate head and let 'ptr' indicate start */
if(ptr==NULL)
{
pre=&front;
ptr=NextNode(pre);
}
}/*for j;*/
printf("Delete monkey %d\n",ptr->data);
ptr=NextNode(ptr);/*delete the node whinch pointer 'ptr' indicated,*/
DeleteAfter(pre);
if(ptr==NULL)/*if 'ptr' indicate "NULL",let "pre"and "ptr" indicate head and start*/
{
pre=&front;
ptr=NextNode(pre);
}
}/*for i;*/
printf("\n");
printf("Monkey %d is the king\n",ptr->data);
DeleteAfter(pre);/*free the last node*/
}
int main()
{
int n,m;
printf("\nInput n and m :");
scanf("%d,%d",&n,&m);
Selete(n,m);

return 0;
}
langmng 2003-12-01
  • 打赏
  • 举报
回复
各位GG 和 MM
注意自己的书写规范,这样的话有利于菜鸟们的成长!
zhangfjj 2003-12-01
  • 打赏
  • 举报
回复
用循环链表来实现
chenzhuo 2003-12-01
  • 打赏
  • 举报
回复
可以考虑定义一个数组,先赋予值,在采用循环将一些特别的元素赋予零,到最后不是零的那个就是要求的那个人,程序可以这么写:
#define NMAX1000
main()
{int i,k,m,n,num[NMAX],*t; /*这里的*t应该为*p*/
printf("please input the number:");
scanf("%d",&n);
p=num;
for(i=0;i<n;i++)
*(p+i)=i+1;
i=0;k=0;m=0;
while(m<n-1)
{if(*(p+i)!=0) k++;
if(k==3)
(*(p+i)==0;k=0; /*这里的应该为{*(p+i)=0;k=0;
m++;}
i++;
if(i==n) i=0;
}
while(*p==0) p++;
printf("tne %d person is the last,ang it's number is %d",n,*p);
}
小弟只是自己想法而已,如有错误望指出。大家彼此交流交流!
xiaomantoubaba 2003-12-01
  • 打赏
  • 举报
回复
约瑟夫问题!数据结构里的!
answerzy 2003-12-01
  • 打赏
  • 举报
回复
没力气打字了
只能说一句,你如果学了数据结构那就简单多了
悠云guo 2003-12-01
  • 打赏
  • 举报
回复
ssbull(初学者) :老大,人家要的是C的,不是C++的
ssbull 2003-12-01
  • 打赏
  • 举报
回复
忘了说,结果中最后一个数就是楼主所需的
ssbull 2003-12-01
  • 打赏
  • 举报
回复
呵呵,刚好自己做了一个这个程序,写的不好,请大家多多指教
楼主说的这个是Josephus问题。这个程序可以从任意位置开始,所报的数也可以是任意定。
#include<iostream>
using namespace std;

class Josephus {
private:
int *array;
int *tmp;
int length;
public:
Josephus(int size);
~Josephus();
void print();
void game(int begin,int num);
};

Josephus::Josephus(int size):length(size) {
array=new int[size];
tmp=new int[size];
for(int i=0;i<size;i++) {
array[i]=i+1;
tmp[i]=0;
}
}

Josephus::~Josephus() {
delete []array;
delete []tmp;
}

void Josephus::print() {
cout<<"Length"<<length<<endl;
for(int i=0;i<length;i++)
cout<<tmp[i]<<" ";
cout<<endl;
}

void Josephus::game(int begin,int num) {
int location;
int i=0;
int temp=length;
while(length>1) {//当数组中的数不止一个时
if((begin+num)>length) location=begin+num-length-1;//确定开始的位置
else location=begin+num-1;
tmp[i]=array[location];//将满足条件的数从数组中剔除
i++;
for(int j=location;j<length-1;j++)//将该位置上的数剔除后,把后面的数往前移
array[j]=array[j+1];
length--;
begin=location;
}
tmp[i]=array[location-1];//数组中的最后一个数
length=temp;
}

void main() {
int number,start,many;
cout<<"Please enter the size of array:";
cin>>number;
cout<<"Please enter the start:";
cin>>start;
cout<<"Please enter the number:";
cin>>many;
Josephus jose(number);
jose.game(start-1,many);
jose.print();

}
happystudy 2003-12-01
  • 打赏
  • 举报
回复
skywarship(小李)所说正确.
dayster 2003-12-01
  • 打赏
  • 举报
回复
上面那个定义的时候搞错 了
应该是int i,k,m,n,num[NMAX],*p;
不好意思!
dayster 2003-12-01
  • 打赏
  • 举报
回复
可以考虑定义一个数组,先赋予值,在采用循环将一些特别的元素赋予零,到最后不是零的那个就是要求的那个人,程序可以这么写:
#define NMAX1000
main()
{int i,k,m,n,num[NMAX],*t;
printf("please input the number:");
scanf("%d",&n);
p=num;
for(i=0;i<n;i++)
*(p+i)=i+1;
i=0;k=0;m=0;
while(m<n-1)
{if(*(p+i)!=0) k++;
if(k==3)
(*(p+i)==0;k=0;
m++;}
i++;
if(i==n) i=0;
}
while(*p==0) p++;
printf("tne %d person is the last,ang it's number is %d",n,*p);
}
小弟只是自己想法而已,如有错误望指出。大家彼此交流交流!
skywarship 2003-12-01
  • 打赏
  • 举报
回复
设置一个n个元素的数组,用数值1表示有人,用0表示此人已退出
设置一个位置指针和一个计数器,从数组头上开始访问并计数,每计到三就将相应位置置0,并重新计数,访问完整个数组后再从头开始,直到数值为1的元素的个数少于三个
最后数组中数值为1的元素的序号就是最后剩下的人的编号

70,037

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧