设有n个人依围成一圈,从第1个人开始报数,数到第m个人出列,然后从出列的下一个人开始报数,数到第m个人又出列, …,如此反复到所有的人全部出列为止。设n个人的编号分别为 1, 2, …, n,打印出出

设有n个人依围成一圈,从第1个人开始报数,数到第m个人出列,然后从出列的下一个人开始报数,数到第m个人又出列,   ,如此反复到所有的人全部出列为止。设n个人的编号分别为   1   2     n ,打印出出列的顺序;要求用   java 实现


public static void main(String args[])
{
List<Integer> source = new ArrayList<Integer>();
List<Integer> out = new ArrayList<Integer>();
for(int i=1;i<=30; i++){
source.add(i);
}
int index=0;
while(source.size() > 0){
index = (index+4)%source.size();
out.add(source.get(index));
source.remove(index);
}
for(int i=0;i<out.size(); i++){
System.out.print(out.get(i) + " ");
}
}
补充:
结果是
5 10 15 20 25 30 6 12 18 24 1 8 16 23 2 11 21 29 13 26 7 22 9 28 19 17 27 4 14 3
5
风弑痕□  的感言: 谢谢了,我还不知道能不能run呢,等我试下啊 ! 2011-04-29

其他回答(3)

基石工作室  初级团 合作回答者: 1人  2011-04-29
有点难
ヤヤ花  3级 2011-04-29

.编程题:设有n个人依围成一圈,从第1个人开始报数,数到第m个人出列,然后从出列的下一个人开始报数,数到第m个人又出列,…,如此反复到所有的人全部出列为止。设n个人的编号分别为1,2,…,n,打印出出列的顺序;要求用java实现。(Core Java)
答:代码如下:
package test;
public class CountGame {
private static boolean same(int[] p,int l,int n){
for(int i=0;i<l;i++){
if(p[i]==n){
return true;
}
}
return false;
}
public static void play(int playerNum, int step){
int[] p=new int[playerNum];
int counter = 1;
while(true){
if(counter > playerNum*step){
break;
}
for(int i=1;i<playerNum+1;i++){
while(true){
if(same(p,playerNum,i)==false) break;
else i=i+1;
}
if(i > playerNum)break;
if(counter%step==0){
System.out.print(i + " ");
p[counter/step-1]=i;
}
counter+=1;
}
}
System.out.println();
}
public static void main(String[] args) {
play(10, 7);
}
}

葫芦娃编程战队  中级团 合作回答者: 1人  2011-04-29

public class Out {

public static int PERSON_COUNT = 30;//总人数

public static int[] getPers(int count) {
int[] temp = new int[count];
for(int i = 1; i <= count; i++) {
temp[i-1] = i;
}
return temp;
}

public static void main(String[] arg) {

int[] pers = getPers(PERSON_COUNT);//初始化数组
boolean[] out = new boolean[PERSON_COUNT];//标识该下标的人是否出列
int[] newPers = new int[PERSON_COUNT];//按出列顺序排列的新数组
//i标识遍历总人数的下标, n表示1到5的数字,count表示多少人出列了
for(int i = 0, n = 1, count=0; i < pers.length; i++) {
//如果该下标的人出列了
if(!out[i]) {
//如果数到5
if(n == 5) {
newPers[count] = pers[i];//将该下标的人加入到底count个出列数组
out[i] = true;//标识该下标的人已经出列
count++;//出列总数+1
n = 0;//数字从新开始数
}
n++;
}
//如果到了人数末尾,从新开始遍历
if(i+1 == pers.length) i = -1;
//如果全部出列
if(count == pers.length) {
break;
}
}

for(int i = 0; i < newPers.length; i++) {
System.out.println("第" + (i + 1) + "个出列的人是:" + newPers[i]);
}

}
}
测试已经通过,输出结果:

第1个出列的人是:5
第2个出列的人是:10
第3个出列的人是:15
第4个出列的人是:20
第5个出列的人是:25
第6个出列的人是:30
第7个出列的人是:6
第8个出列的人是:12
第9个出列的人是:18
第10个出列的人是:24
第11个出列的人是:1
第12个出列的人是:8
第13个出列的人是:16
第14个出列的人是:23
第15个出列的人是:2
第16个出列的人是:11
第17个出列的人是:21
第18个出列的人是:29
第19个出列的人是:13
第20个出列的人是:26
第21个出列的人是:7
第22个出列的人是:22
第23个出列的人是:9
第24个出列的人是:28
第25个出列的人是:19
第26个出列的人是:17
第27个出列的人是:27
第28个出列的人是:4
第29个出列的人是:14
第30个出列的人是:3

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 这是一个依次围成一圈,从第1个人开始报数数到第m个人出列,然后从出列的下一个人开始报数数到第m个人出列,...直到剩余所有人全部出列的问题。设有n个人编号分别为1,2,...,n,那么第i个人编号为i的人,那么编码为1~n的个人依次出列第i个人编号为序号i,打印出列的顺序。 ### 回答2: 这道题是一道经典的约瑟夫问题,可以用循环队列来解决。 首先将n个人编号放入队列中,并从队首开始报数,每数到m时,将该位置的人出列。然后从出列位置的下一个人重新开始报数,直到最后一个出列。 具体来说,可以使用一个数组queue来表示队列,queue[i]存储第i个人编号一个指针front表示队首位置,一个指针rear表示队尾位置。初始时,front=rear=0。 首先将所有人的编号放入队列中: ``` for(int i=1; i<=n; i++) { queue[rear++] = i; } ``` 然后开始报数,每数到m时将出列位置的人队: ``` int cnt = 0; // 当前已数的人数 while(front != rear) { // 队列非空时循环 int cur = queue[front]; // 当前出列的人 if(++cnt == m) { // 数到m时出列 printf("%d ", cur); front++; // 出列位置后移 cnt = 0; // 重新开始计数 continue; } queue[rear++] = cur; // 报数未到m时,当前人从队尾进队 front++; // 队首后移 } ``` 最后所有人都队时,就得到了出列的顺序。 完整代码如下: ### 回答3: 这是一个经典的约瑟夫问题,可以使用循环链表来模拟解决。将所有的人编号依次插入一个循环链表中,然后从头结点开始,依次遍历链表进行操作。具体步骤如下: 1. 定义一个循环链表结构体,包含成员变量:编号num,指向下一个结点的指针next。 2. 创建一个有n个结点的循环链表。 3. 定义两个变量:count和index,表示数数的个数和当前结点的下标(从0开始)。 4. 从头结点开始,依次遍历链表进行操作: a. 如果当前结点是最后一个结点,则将index重置为0。 b. 如果count等于m-1,则删除当前结点,并将该结点的下一个结点作为新的当前结点,同时打印该结点的编号。 c. 如果count不等于m-1,则将count加1,继续遍历下一个结点。 5. 重复步骤4,直到链表为空。 6. 打印所有人出列的顺序。 具体代码如下: ```c #include <stdio.h> #include <stdlib.h> // 定义循环链表结构体 typedef struct Node { int num; // 编号 struct Node *next; // 下一个结点指针 } Node; int main() { int n, m; printf("请输入人数n和报数的数m:"); scanf("%d%d", &n, &m); // 创建循环链表 Node *head = (Node *)malloc(sizeof(Node)); Node *p = head; for (int i = 1; i <= n; i++) { Node *node = (Node *)malloc(sizeof(Node)); node->num = i; p->next = node; p = node; } p->next = head->next; // 循环链表尾结点指向头结点 int index = 0, count = 0; while (head->next != head) { // 循环链表不为空 if (index == n) { // 如果当前结点是最后一个结点,则将下标重置为0 index = 0; } if (count == m - 1) { // 如果数数的个数等于m-1,则删除当前结点 Node *q = head->next; for (int i = 0; i < index - 1; i++) { // 找到上一个结点位置 q = q->next; } printf("%d ", q->next->num); // 打印出列编号 Node *temp = q->next; // 删除当前结点 q->next = q->next->next; free(temp); count = 0; // 重置计数器 } else { // 继续遍历下一个结点 index++; count++; head = head->next; } } free(head); // 释放头结点内存 return 0; } ``` 例如,当输入n=8,m=3时,最后的出列顺序为:3 6 1 5 2 8 4 7。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值