C语言循环链表解决约瑟夫问题

1

Joseph Problem(35分)

题目内容:

實作Joseph problem.

假設一開始有N個人,編號1~N,

按照順序以順時針圍成一個圓圈。

遊戲開始時,編號1的人拿刀。

之後每一輪刀子會被往下傳M個人,

而當輪最後拿到刀子的人會將他的下一個人殺掉,

殺完後刀子會再傳給被殺的下一個人。

這樣一輪就算結束。

遊戲會進行許多輪,直到只剩下最後一個人。

範例1:N=5, M=2

第一輪:刀子傳給3號,4號被殺,刀子再傳給5號 (1 2 3 5)

第二輪:刀子傳給2號,3號被殺,刀子再傳給5號 (1 2 5)

第三輪:刀子傳給2號,5號被殺,刀子再傳給1號 (1 2)

第四輪:刀子傳給1號,2號被殺,最後1號存活。

範例2:N=4, M=3

第一輪:刀子傳給4號,1號被殺,刀子再傳給2號 (2 3 4)

第二輪:刀子傳給2號,3號被殺,刀子再傳給4號 (2 4)

第三輪:刀子傳給2號,4號被殺,最後2號存活。

输入格式:

輸入第一行為一個數字T,代表測資的筆數。

接下來會有T筆測資,每一筆測資一行,

會有兩個數字N,M,數字間以空格區隔。

數字範圍:

T < 1000

0 < N <= 1000

0 < M <= 1000

输出格式:

輸出一行數字,將每筆測資最後存活下來的人的編號加總。

输入样例:

3

5 2

4 3

8 4

输出样例:

4

#include <stdio.h>
#include <stdlib.h>

#define ERROR NULL
typedef int ElementType;
typedef struct LNode *PtrToLNode;
struct LNode {
	ElementType Data;
	PtrToLNode Next;
};
typedef PtrToLNode Position;
typedef PtrToLNode List;

Position Find(List L, ElementType X);
List Insert(List L, ElementType X, Position P);
List Delete(List L, Position P);

int main()
{
	int N, n, m;
	int ans = 0;
	scanf_s("%d", &N);
	while (N--)
	{
		List L;
		L = NULL;
		scanf_s("%d %d", &n, &m);
		for (int i = n; i >=1; i--)
		{
			L = Insert(L, i, L);
		}
		PtrToLNode p, q, temp;
		p = L;
		while (p->Next)
		{
			//printf("%d ", p->Data);
			p = p->Next;
		}
		p->Next = L;
		q = L;
		while (q->Next != q)
		{
			for (int i = 1; i <=m; i++)
			{
				q = q->Next;
			}
			temp = q->Next;
			q->Next = temp->Next;
			free(temp);
			q = q->Next;
		}
		ans += q->Data;
		//printf("%d\n", q->Data);
	}
	printf("%d\n", ans);
	
	
}

List Insert(List L, ElementType X, Position P)
{
	PtrToLNode Current;
	PtrToLNode p = (PtrToLNode)malloc(sizeof(struct LNode));
	if (P == L)       // 如果要插入的元素就是头节点
	{
		p->Data = X;
		p->Next = L;
		L = p;
		return L;
	}
	Current = L;
	while (Current&&Current->Next != P)
	{
		Current = Current->Next;
	}

	if (Current == NULL)
	{
		printf("Wrong Position for Insertion\n");
		return ERROR;
	}

	p->Data = X;
	p->Next = Current->Next;
	Current->Next = p;
	return L;
}

Position Find(List L, ElementType X)
{
	PtrToLNode p = L;
	while (p)
	{
		if (p->Data == X)
			return p;
		p = p->Next;
	}
	return ERROR;

}


List Delete(List L, Position P)
{
	PtrToLNode p = L;
	PtrToLNode temp;
	if (p == P)              // 如果删除的是头节点
	{
		L = L->Next;
		free(p);
		return L;
	}
	while (p&&p->Next != P)
	{
		p = p->Next;
	}

	if (p == NULL)           // 如果找不到要删除的节点
	{
		printf("Wrong Position for Deletion\n");
		return ERROR;
	}

	temp = p->Next;
	p->Next = temp->Next;
	free(temp);
	return L;
}

猜你喜欢

转载自blog.csdn.net/wwxy1995/article/details/83317666