27ジョセフ・中央
著者:ZhouMingLiang制限時間:10S章:1次元配列
問題の説明:
ある時、同社は明らかに忘年会を開催しました。忘年会のクライマックスは最後のリンクになりたいことはありません。企業の活性を高めるために、宝くじの抽選の伝統的な方法に従うが、ゲームを持っていませんでした。最後に残った人が賞品を得るでしょうしながら、ステップバイステップでは、人々を排除します。
その後、サークル内のすべての会社の従業員の第一に、とは、Xのうちの数を決定し、その後、彼らは、Xへのカウントは、その人が排除されるだろうというとき、1つのカウントから、それらのいずれかから開始します。このゲームは、次の通りれますその後、次の人、その後、1つのカウントから、その人は最終的に大賞受賞者であることを、最後に残った一人になるまで繰り返されました。
例えば、会社が5人を持って、2の数の集合のうち、5人の始まりは、円形に配置され、番号が付けられている:1,2,3,4,5、
まず、人々の数から2をカウントし、1を数えるようになりました排除番号2の後に、その4つだけのこと:; 1,3,4,5-は
、その後、数2、数4うちに、人3の数を数えるので、わずか3人ということを開始します:1,3、 5は、
その後、5人の数をカウントし始め、数2、数1アウト、2つだけの個人がそうすることを:3,5;
3人からの最終的な数がカウント開始、数5アウト2の数、その人が、最終的な賞の3を取得するための最後の数。(注:上記のシーケンスが3 2415排除されます)排除することが悪いことに明らかに非常に幸運、そして最後に二ので、非常に落ち込んで賞を逃しました。彼は、彼は明らかにプログラム、彼はあなたに言っています人々の数を書くため、その数はさらに次の2つに応じてプログラムできることを教えてくれ排除置くために、あなたに好意をお願いしたいと思いますので、それが解消されたことを全体のプロセスを知りたいと思いました出力シーケンスのうちの人々の計算、すなわち、数人のうちの最良のシーケンス番号。
明らかに質問がに沸く:あなたの会社の数Nを与え、数値Xを排除し、あなたのプログラムのシミュレーションのうちの方法は、上記の順序のうち人の数の出力を説明しました。説明を入力します。
你写的程序要求从标准输入设备中读入测试数据作为你所写程序的输入数据。标准输入设备中有多组测试数据,每组测试数据仅一行,每组测试数据有两个整数N(1<N<100)和X(0<X<10),N表示公司的人数,X表示淘汰数,两个整数用一个空格隔开。每组测试数据与其后一组测试数据之间没有任何空行,第一组测试数据前面以及最后一组测试数据后面也都没有任何空行。
输出说明 :对于每一组测试数据,你写的程序要求计算出一组相应的运算结果,并将这一组运算结果作为你所写程序的输出数据依次写入到标准输出设备中。每组运算结果为N个整数,即淘汰人的编号的顺序,每个数之间用一个空格隔开。每组运算结果单独形成一行数据,其行首和行尾都没有任何空格,每组运算结果与其后一组运算结果之间没有任何空行,第一组运算结果前面以及最后一组运算结果后面也都没有任何空行。
注:通常,显示屏为标准输出设备。 输入范例 : 5 2 5 6 99 1 输出范例 : 2 4 1 5 3 1 3 2 5 4 1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
97 98 99
代码:
/*
约瑟夫环
*/
#include<stdio.h>
#define MAX_SIZE 102
typedef struct Person {
int num;// 人员编号
struct Person* next;
} Person;
int main() {
int N = 0, X = 0;
int i = 0;
Person* head = (Person* )malloc(sizeof(Person));
Person* person = NULL;// 用于新建结点
Person* rear = head;// rear始终指向链表尾部
Person* p = NULL;// 工作指针
Person* pre = NULL;// 工作指针前驱
Person* temp = NULL;// 用于暂存被删除结点
int outCount = 0;// 出环人员数量
int count = 0;
head -> next = NULL;
while (scanf("%d%d", &N, &X) != EOF) {
head -> next = NULL;// 每次开始前重置数据
rear = head;
outCount = 0;
for (i = 1; i <= N; i++) {// 建立链表
person = (Person* )malloc(sizeof(Person));
person -> num = i;
person -> next = NULL;
rear -> next = person;
rear = person;
}/* 建表过程没问题*/
rear -> next = head -> next;// 构成循环链表
p = head -> next;
pre = head;
count = 1;// 开始计数
while (1) {
if (count == X) {
temp = p;
if (outCount == 0)
printf("%d", temp -> num);
else
printf(" %d", temp -> num);
pre -> next = p -> next;// 删除结点
p = p -> next;
free(temp);
count = 1;// 重置计数
if (++outCount == N) {
printf("\n");
break;
}
}
else {
count++;
pre = p;
p = p -> next;
}
}
}
return 0;
}
做的过程中忘记重置了,结果后面死循环……