一道三级的上机题???

linenyu 2003-09-10 10:24:23
设有n个人围坐并按顺时针方向从1到n编号,从第s个人开始进行1到m的报数,报数到第m个人的时候,此人出圈,再从他的下一个人重新开始1到m的报数,如此进行下去,直到所有人出圈为止,现要求按出圈顺序,每十个人一组,给出这个人的顺序表。求编制Josegh()函数实现。
设 n=100,s=1,m=10
...全文
36 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
Benny1 2003-09-11
  • 打赏
  • 举报
回复
#include <iostream>
#include <vector>
#include <iomanip>
using namespace std;

void main(void)
{
const int LENGTH = 17; // 总人数
const int STEP = 3; // 间隔数
const int BEGIN = 1; // 开始号码
vector<int> v_p; // 动态数组,保留剩余人员号码
int mlen = (BEGIN - 1)%STEP;// 循环一圈余数
int i, j;

// 开始人员编号0 ~ (LENGTH - 1)
for (i = 0; i < LENGTH; ++ i)
{
v_p.push_back(i);
if (i < 10)
cout << setw(2) << setiosflags(ios::left) << i;
else
cout << setw(3) << setiosflags(ios::left) << i;
}
cout << endl;

int size = v_p.size();
int lastv = 0;
while (size > 1)
{
// 开始循环一圈
vector<int>::iterator iter = v_p.begin() + STEP - mlen - 1;
for (i = 0; i < (size + mlen)/STEP; ++ i)
{
if (iter >= v_p.begin() && iter < v_p.end())
{
for (j = lastv; j < *iter; ++ j)
{
if (j < 10)
cout << " ";
else
cout << " ";
}
if (*iter < 10)
cout << "x ";
else
cout << "x ";

lastv = *iter + 1;

// 删除选中号码,并获取下一号码
iter = v_p.erase(iter) + STEP - 1;
}
}
cout << endl;

lastv = 0;

// 此次循环余数
mlen = (size + mlen) % STEP;

// 此次循环剩余人员
size = v_p.size();
}

for (j = 0; j < v_p[0]; ++ j)
{
if (j < 10)
cout << " ";
else
cout << " ";
}
cout << "o" << endl;
cout << "最后号码: " << v_p[0] << "号" << endl;
}



----------------






zyu

性别:男

等级:飞虫

普通村民 发表时间:2003-6-7 21:11:50

--------------------------------------------------------------------------------


输出结果:

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
x x x x x
x x x x
x x x
x x
x

x
o
最后号码: 10号




leechildren 2003-09-11
  • 打赏
  • 举报
回复
给你些主要代码, 你自己去完成创建链表等函数。

struct person{
int no;
struct person *next;
};
struct person *create(int n);

main()
{
struct person *head,*p,*pv;
int n=100;/*人数*/
int m=10; /*退出圆圈的报数*/
int k=0; /*记数器*/
head=create(n); /*创建链表*/
while(head->next!=NULL)
{pv=p=head;
while(p!=NULL)
{
k++;
if(k%m==0) /*记数到m,删除结点*/
{
printf(“%d\n”,p->no);
if(p==head)head=head->next; /*如果为第一个结点,则修改头指针*/
else pv->next=p->next; /*删除中间结点*/
p=p->next;
k=0; /*记数器清零*/
}
else {pv=p;
p=p->next;
}
}
}
printf(“The Last One: %d\n”,head->no); /*打印剩余的最后一个*/
}

struct person *create(int n)
{
struct person *h,*p;
int i=0;
h=p=NULL;
while(i<n)
{
p=(struct person *)malloc(sizeof(struct person));
p->no= n - i;
p->next=h;
h=p;
i++;
}
return h;
}
ZhangYv 2003-09-11
  • 打赏
  • 举报
回复
http://expert.csdn.net/Expert/topic/2059/2059607.xml?temp=.1439173
这里有,我忘记贴在哪里了,太多。
bluedodo 2003-09-11
  • 打赏
  • 举报
回复
晕,这个题为什么不用链表
linenyu 2003-09-11
  • 打赏
  • 举报
回复
好象运行不能通过的,通过的话马上结贴。不用链表的原因很简单呀,上面不说的吗,三级还不至于用到链表。不用链表都不知道用上链表不傻的。题外话的
WYlslrt 2003-09-11
  • 打赏
  • 举报
回复
又写错了,太马虎,那个if(j==19)后面不是j=0而是j=-1
WYlslrt 2003-09-11
  • 打赏
  • 举报
回复
看错题了,反正大体思路就是这样。把20改为n就行了。惯性思维,原来有一个和这类似的题。
WYlslrt 2003-09-11
  • 打赏
  • 举报
回复
我用c写的没有任何指针,只用了一个数组,自己看看吧

#include < stdio.h >

int man[20], count;
void result(int i);

main(void)
{
int k;
for(k = 0; k < 20; ++ k)
{
man[k] = 1;
}

scanf("%d", & count);
if(count == 0) printf("please input 1-100.\n")
;
else result(count);
return 0;
}

void result(int i)
{
int j, k, num;
k = 0;
num = 0;
for(j = 0; j < 20; ++ j)
{
if(man[j])
{
k++ ;
if(k == i)
{
man[j] = 0;
num++ ;
k = 0;
}
}

if(j == 19)
j = 0;
if(num == 19)
break;
}

for(j = 0; j < 20; ++ j)
{
if(man[j]) printf("There is NO.%d only here\n", j + 1)
;
}

return 0;


}

linenyu 2003-09-11
  • 打赏
  • 举报
回复
参考书上的答案是以下,根本就没有连表什么的,考三级不是高程的,帮忙解释一下吧
void Josegh(void)
{
int i,s,k,sl,w;
sl=s;
for(i=1;i<=n;i++)
for(i=n;i>=2;i--)
{sl=(sl+m-1)%i;
if(sl==0)
sl=i;
w=p[sl-1];
for(j=sl;j<=i-1;j++)
p[j-1]=p[j];
p[i-1]=w;
}
声明一下,上面是我同学从参考书上看的,有些变量什么的,前面已经说的,还有的看看应该能明白的,上面程序肯定有错的,大方向是这样的,字写的太难看的,看不青的。想请高手解释一下,顺便改一下的。不要再改成什么表,栈的。麻烦
lixingyi 2003-09-11
  • 打赏
  • 举报
回复
可以使用队列,边进边出
binjuny 2003-09-11
  • 打赏
  • 举报
回复
约瑟夫问题
这是17世纪的法国数学家加斯帕在《数目的游戏问题》中讲的一个故事:15个教徒和15 个非教徒在深海上遇险,必须将一半的人投入海中,其余的人才能幸免于难,于是想了一个办法:30个人围成一圆圈,从第一个人开始依次报数,每数到第九个人就将他扔入大海,如此循环进行直到仅余15个人为止。问怎样排法,才能使每次投入大海的都是非教徒。
*问题分析与算法设计
约瑟夫问题并不难,但求解的方法很多;题目的变化形式也很多。这里给出一种实现方法。
题目中30个人围成一圈,因而启发我们用一个循环的链来表示。可以使用结构数组来构成一个循环链。结构中有两个成员,其一为指向下一个人的指针,以构成环形的链;其二为该 人是否被扔下海的标记,为1表示还在船上。从第一个人开始对还未扔下海的人进行计数,每数到9时,将结构中的标记改为0,表示该人已被扔下海了。这样循环计数直到有15个人被扔下海为止。
*程序与程序注释
#include<stdio.h>
struct node
{
int nextp; /*指向下一个人的指针(下一个人的数组下标)*/
int no_out; /*是否被扔下海的标记。1:没有被扔下海。0:已被扔下海*/
}link[31]; /*30个人,0号元素没有使用*/
void main()
{
int i,j,k;
printf("The original circle is(+:pagendom,@:christian):\n");
for(i=1;i<=30;i++) /*初始化结构数组*/
{
link[i].nextp=i+1; /*指针指向下一个人(数组元素下标)*/
link[i].no_out=1; /*标志置为1,表示人都在船上*/
}
link[30].nextp=1; /*第30个人的指针指向第一个人以构成环*/
j=30; /*j:指向已经处理完毕的数组元素,从link[i]指向的人开始计数*/
for(i=0;i<15;i++) /*i:已扔下海的人数计数器*/
{
for(k=0;;) /*k:决定哪个人被扔下海的计数器*/
if(k<15)
{
j=link[j].nextp; /*修改指针,取下一个人*/
k+=link[j].no_out; /*进行计数。因已扔下海的人计标记为0*/
}
else break; /*计数到15则停止计数*/
link[j].no_out=0; /*将标记置 0,表示该人已被扔下海*/
}
for(i=1;i<=30;i++) /*输出结果*/
printf("%c",link[i].no_out? '@':'+'); /*+:被扔下海, @:在船上*/
printf("\n");
}
*运行结果
The original circle is(+:pagandom, @:christian):
+++@@+@+@@@+@+++@@+@@@+++@+@@+
(+"表示被扔下海海的非教徒 @:留在船上活命的教徒)

*思考题
有N个小孩围 成一圈并依次编号,教师指定从第M个小孩开始报数,报到第S个小孩即令其出列。然后从下一个孩子继续报数,数到第S个小孩又令其出列,如此直到所有的孩子都出列。求小孩出列的先后顺序。

binjuny 2003-09-11
  • 打赏
  • 举报
回复
//用来实现的约瑟夫环问题
#include <iostream.h>
#include <fstream.h>
void main()
{
int n,cs,s=0,i,j;//n:人数;cs:密码;s第几个人出列;i,j:循环用变量
ifstream input("myindata.txt");
input>>n>>cs>>s;
cout<<"人数:"<<n<<" 出始密码"<<cs<<" 初始是第几个人:"<<s<<endl;
int* sz=new int[n+1];
int* sz1=new int[n+1];
for(i=1;i<=n;i++)
{
input>>sz[i];
sz1[i]=i;
cout<<sz[i]<<" ";
}
cout<<endl;
for(i=n;i>=1;i--)
{
s=(s+cs-1)%i;
if(s==0) s=i;
cs=sz[s];
cout<<"第"<<sz1[s]<<"个人出列"<<"密码是:"<<cs<<endl;
for(j=s;j<i;j++)
{
sz[j]=sz[j+1];
sz1[j]=sz1[j+1];
}
}
delete sz;
cin>>i;
}
CAT323 2003-09-11
  • 打赏
  • 举报
回复
解题思路:
1:建立一个首尾相连的链表,读入数据(data)
2:指针循环移动10个节点,这个步促是一直循环进行
3:删除节点
4:按出节点的顺序建立一个新链表
(3.4两步是包含在2点中循环执行的)
5:输出新链表
源程序晚点回你
cnxiaohai 2003-09-11
  • 打赏
  • 举报
回复
实在不会链表

用数组也好
zbstone 2003-09-11
  • 打赏
  • 举报
回复
我看到过这个题目
应该没有上面两位的那么长
用一个巧妙的数学方法解答的
不需要链表!
不用考虑的太多!
dreamfly8848 2003-09-11
  • 打赏
  • 举报
回复
mark
linenyu 2003-09-10
  • 打赏
  • 举报
回复
简单易懂的呀
最好给出注解呀
mickwang 2003-09-10
  • 打赏
  • 举报
回复
随便一本数据结构的书上都有n种实现
Ilovecoding 2003-09-10
  • 打赏
  • 举报
回复
作业题吧?好像没人给出代码,自己努力!

69,373

社区成员

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

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