有n个人围成一圈,顺序排号,从第一个开始报数(从1到3报数),凡报到3的人退出圈子,问最后最后留下的是原来第几号的哪位。
其实有很多的算法来解决这样的问题,这边我采用的是数据结构中的队列来解决这个问题。
具体思路是:每隔两个(counts++ % 3 == 0 )就弹出队列,前几个(count++ % 3 != 0)弹出队列后在push到队列的尾部。这样当队列的元素数量剩最后一个时候,就是所求的元素。
int main(void) {
Queue * queue = NULL;
queue = init();
int i = 0;
for(i = 1;i<=99;i++)
{
push(queue,i);
}
//解题思路
i = 1;
while(queue->size != 1)
{
int data = pop(queue);
if(i++ % 3 != 0)
{
push(queue,data);
}
else
{
printf("killed id is:%d\n",data);
}
}
//所求的元素是:
printf("last person id is :%d\n",pop(queue));
return EXIT_SUCCESS;
}
队列头文件的设计:
#ifndef QUEUE_H_
#define QUEUE_H_
#define LEN 100
typedef struct Node
{
int data;
struct Node * next;
struct Node * prev;
}Node;
typedef struct Queue
{
int size;
Node * head;
Node * tail;
}Queue;
Queue * init();
void push(Queue * queue,int data);
int pop(Queue * queue);
void travel(Queue * quque);
#endif /* QUEUE_H_ */
队列头文件的实现:
#include "Queue.h"
#include <stdio.h>
#include <stdlib.h>
Queue * init()
{
Queue * queue = (Queue*)malloc(sizeof(Queue));
if(queue == NULL)
{
perror("malloc error");
exit(-1);
}
memset(queue,0,sizeof(Queue));
queue->size = 0;
queue->head = NULL;
queue->tail = NULL;
return queue;
}
void push(Queue * queue,int data)
{
if(queue->size == LEN)
{
perror("over flow");
exit(-1);
}
Node * node = malloc(sizeof(Node));
if(node == NULL)
{
perror("malloc error");
exit(-1);
}
node->data = data;
node->next = 0;
node->prev = 0;
//-------------
if(queue->size == 0)
{
queue->head = node;
}
else
{
queue->tail->next = node;
node->prev = queue->tail;
}
queue->tail = node;
queue->size++;
}
int pop(Queue * queue)
{
if(queue->size == 0)
{
printf("empty!");
exit(-1);
}
Node * node = queue->head;
int data = node->data;
queue->head = node->next;
free(node);
queue->size--;
return data;
}
void travel(Queue * queue)
{
printf("----------\n");
Node * node = queue->head;
while(node)
{
printf("%d\t",node->data);
node = node->next;
}
printf("----------\n");
}
总结:在C语言里没有C++中的STL,这些数据结构需要自己实现。所以相对麻烦一点,在C++里面也就10行代码吧。