关于面试题中的约瑟夫循环我的解法

来源:互联网 发布:武汉有单片机培训机构 编辑:程序博客网 时间:2024/04/28 13:05
有一个数组a[1000]存放0-1000,要求每隔二个数删除一个数,到末尾时循环到开头继续进行,求最后一个被删掉数的原始下标。

这是题目。我做了一个通用解法,做的不好,希望大家指出错误。下面是代码。
#define _CRT_SECURE_NO_WARNINGS#include <stdio.h>#include <stdlib.h>#include <malloc.h>#include <time.h>//用来查看使用了多少时间。/*循环版*/void main1(){int a[100];int num,death;//num表示输入的总人数,death表示输入的出局编号printf("亲输入总人数,小于100人\n");scanf("%d",&num);printf("请输入淘汰序号\n");scanf("%d", &death);int count = 0;//进行计算运行了多少次int i=0, j=0;for (int temp = 0; temp <= num; temp++)a[temp] = 1;while (1){if (a[i%num] == 1){j++;}if (j == death){a[i%num] = 0;j = 0;count++;if (count == (num))break;//当运行到最后一个时退出循环printf("现在%d被淘汰\n", i%num + 1);}i++;}printf("最后一个活下来的是第%d号\n", i%num+1);system("pause");}/*链表版*/typedef struct node{int num;struct node *next;}node;//结构体的定义typedef struct node *Link; /* 定义LinkList */void init(Link *l)//初始化,如果不以指针的地址传入的话就会导致指针不被初始化{*l = (Link)malloc(sizeof(Link));(*l)->num = 0;(*l)->next = NULL;}void main(){clock_t start, finish;//计算加printf和加printf的时间区别,事实证明加printf会大大增加运行时间double  duration;//运行时间int num, death;printf("亲输入总人数\n");scanf("%d", &num);printf("请输入淘汰序号\n");scanf("%d", &death);Link l=NULL;init(&l);Link p = NULL;//链表初始化变量Link q = NULL;q = l;start = clock();for (int i = 1; i < num; i++){p = (Link)malloc(sizeof(node));//链表需要申请空间p->num=i;p->next = NULL;q->next = p;q = p;}q->next = l;//循环链表p = NULL;Link temp = NULL;temp = l;while (temp->next != temp){for (int i = 1; i <= death-1 ; i++)//{p = temp;temp = temp->next;}//printf("现在%d被淘汰\n", temp->num + 1);p->next = p->next->next;//free(temp);temp = p->next;}finish = clock();duration = (double)(finish - start) / CLOCKS_PER_SEC;printf("%f seconds\n", duration);printf("最后活下来的是%d\n", temp->num+1);printf("最后活下来的是%d\n", l->num + 1);//头节点似乎不能被删除system("pause");}/*尹成版*/#include <stdio.h>   #include <stdlib.h>  typedef struct stLIST{int index;stLIST *next;}LIST, *PLIST;//创建循环链表  PLIST CreateRoundList(int size){PLIST head = NULL;PLIST temp = (PLIST)malloc(sizeof(LIST));temp->index = 0;temp->next = NULL;head = temp;for (int i = 1; i < size; i++){temp->next = (PLIST)malloc(sizeof(LIST));temp = temp->next;temp->index = i;temp->next = NULL;}//尾部指向头部,构造循环链表  temp->next = head;return head;}PLIST DeleteNode(PLIST head){//判断是否只有一个节点了  while (head != head->next){//指向head的下一个节点  head = head->next;//保存要删除节点的指针  PLIST temp = head->next;//删除节点  head->next = head->next->next;free(temp);//指向刚才删除的节点的下一个节点  head = head->next;//继续循环  }return head;}int main3(){PLIST head = CreateRoundList(1000);printf("剩下的数的下标:%d\n", DeleteNode(head)->index);return 0;}

0 0