1354 新新约瑟夫

来源:互联网 发布:多方电话会议 软件 编辑:程序博客网 时间:2024/04/29 09:41
 
描述

约瑟夫最近不玩约瑟夫问题和新约瑟夫问题,又玩腻了……

他又改了一下规则:有N个人围成一圈,从1号开始,报数,报1,2,3…K,报到K的人出列,然后接下来的那个人开始报K,倒着报K-1…1,还是报到K的人出列,之后又从1到K,又K回到1……请问最后剩下的人是谁……

(要求:软件学院08级本周练习必须使用C风格链表,否则不记成绩)

输入

第一行包含一个整数T表示有T组数据。

每组数据包含两个整数N,K,表示有N个人,报数出列是K。(N<=1000,K<=3000)

输出

对于每组数据按照题目描述要求输出最终剩余人的编号。

样例输入
1
5 3
样例输出
5

 

 

继续链表来做

#include <stdio.h>#include <stdlib.h>/* 定义链表节点类型 */typedef struct node{    int data;    struct node *next;}linklist;int main(){    int i, n, k, m, total;    linklist *head, *p, *s, *q,*s1;    /* 读入问题条件 */int number,te;scanf("%d",&number);for(te=1;te<=number;te++){      scanf("%d %d", &n,&m);    k=1;         /* 创建循环链表,头节点也存信息 */    head = (linklist*) malloc(sizeof(linklist));    p = head;    p->data = 1;    p->next = p;    /* 初始化循环链表 */    for (i = 2; i <= n; i++)    {        s = (linklist*) malloc(sizeof(linklist)); s1 = (linklist*) malloc(sizeof(linklist)); s1=s->next;        s->data = i;        s->next = p->next;        p->next = s;        p = p->next;    }       p = head;      /* 保存节点总数 */    total = n;      q = head;    /* 只剩一个节点时停止循环 */    while (total != 1)    {        /* 报数过程,p指向要删除的节点 */        for (i = 1; i < m; i++)        {            p = p->next;        }        /* 打印要删除的节点序号 */               /* q 指向 p 节点的前驱 */        while (q->next != p)        {            q = q->next;        }        /* 删除 p 节点 */        q->next = p->next;        /* 保存被删除节点指针 */        s= p;        /* p 指向被删除节点的后继 */        p = p->next;        /* 释放被删除的节点 */        free(s);        /* 节点个数减一 */        total--;if(total==1)break;q->next=p->next;s1=p;p=p->next;free(s1);total--;for(i=1;i<=m-1;i++)p=p->next;           }    /* 打印最后剩下的节点序号 */    printf("%d\n", p->data);    free(p);}       return 0;}