有一个数组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;
}