SDUTOJ 1197 约瑟夫问题——循环链表解法数学解法和循环队列
2014-03-29 00:52
477 查看
题目描述
n个人想玩残酷的死亡游戏,游戏规则如下:n个人进行编号,分别从1到n,排成一个圈,顺时针从1开始数到m,数到m的人被杀,剩下的人继续游戏,活到最后的一个人是胜利者。
请输出最后一个人的编号。
输入
输入n和m值。输出
输出胜利者的编号。示例输入
5 3
示例输出
4
提示
第一轮:3被杀第二轮:1被杀第三轮:5被杀第四轮:2被杀#include <stdio.h> #include <stdlib.h> struct node { int data; struct node *next; }; int main() { int n,m,flag=0,i; struct node *head,*p,*q,*r; p=(struct node *)malloc(sizeof(struct node));//游动指针 p->next=NULL; r=(struct node *)malloc(sizeof(struct node));//标记指针 r->next=NULL; head=(struct node *)malloc(sizeof(struct node));//头指针 head->data=1;//头必定为1 head->next=NULL; p=head;//游动指针一开始指向头 scanf("%d%d",&n,&m); for(i=2;i<=n;i++) { q=(struct node *)malloc(sizeof(struct node));//开链节 q->data=i;//为每个链结赋值 p->next=q; q->next=NULL; p=q;//游动指针向后移动 } p->next=head;//连接成环 p=head;//游动指针开始遍历 while(p->next!=p)//设置跳出条件,如果一个链结的尾指针存的是这个链结的头的话,那么就说明就剩下一个链结了,此时跳出循环 { if(flag==0)//如果画图可以发现,第一次实际上指针只移动了(m-1)次 { for(i=0;i<m-1;i++) { r=p;//标记p的上一个链结 p=p->next; } flag=1; } else//其他情况下指针移动m次 { for(i=0;i<m;i++) { r=p;//标记p的上一个链结 p=p->next; } } r->next=p->next;//删除链结 } printf("%d\n",p->data);//打印最后剩下的那个编号 return 0; }
其实还有更简单的方法:(数学方法)
<span style="font-size:24px;">#include <stdio.h> int main() { int n, m, i, s = 0; scanf("%d%d", &n, &m); for (i = 2; i <= n; i++) { s = (s + m) % i; } printf ("%d\n", s+1); return 0; }</span>
这个方法是我在下面的这位大哥的博客里看到的...下面是他的链接
http://www.cnblogs.com/EricYang/archive/2009/09/04/1560478.html
后来想了想,这个用循环队列也能实现,比链表简单多了,就是一个下标的运算,类似于那个数学解法,不过这也是一种方法,代码没写,自己去思考吧...
相关文章推荐
- 约瑟夫问题循环链表解法、队列解法
- [1197]约瑟夫问题 (循环链表)SDUT
- 约瑟夫问题 sdutoj 1197
- [1197]约瑟夫问题 (循环链表)SDUT
- 约瑟夫问题的数学解法
- 约瑟夫问题的数学解法
- 约瑟夫问题数学解法
- poj3517:约瑟夫问题的数学解法
- 约瑟夫问题的数学角度分析 C 数组实现 循环链表实现 递归实现时间复杂度O(logN)
- 约瑟夫问题的数学解法(报数长度不定)
- 约瑟夫问题的数学解法
- 约瑟夫问题的数学解法
- 2746 约瑟夫问题(单向循环链表解法)
- 约瑟夫问题数学解法
- 选猴王(约瑟夫问题的数学解法)
- 约瑟夫问题的数学解法
- 约瑟夫问题的数学解法
- 约瑟夫问题的数学解法
- 约瑟夫问题数学解法
- sdut 1197-约瑟夫问题(循环链表)