Problem A: 用链表实现约瑟夫环 Problem B: 用链表实现登记成绩

Problem A: 用链表实现约瑟夫环

Description

你听说过约瑟夫问题吗?问题大致如下:首先n个人围成一个圈,标记为1到n号。接着,从1号开始报数(从1开始),然后2号报数,然后3号。。。当有人报到到m时,这个人就要踢出比赛,然后从被踢出的人的下一个人开始,重新报数(从1开始)。这样经过n-1次后,就只剩下了一个人,问最后剩下的那个人是几号?

Input

第1行为T,表示有T组数据;

第2行到第T+1开始,每行输入n和m,n表示有几个人,m为上述的每报数m次就要踢出一个人

1=<n<=100, 1=<m<=100

Output

一个数,表示最后剩下了几号

Sample Input

2
5 3
6 4

Sample Output

4
5

结构化有序链表 约瑟夫环

真的 单纯链表来做的话 我觉得c语言班里能做出来的不多

这里 go_through 用到循环链表的思想
c++跟c的区别 我这里只有输入和输出的差别

哦对了 我这里没有释放内存 可以加一点free掉

#include<iostream>
#include<cstdlib>
using namespace std;

int t,n,m,n_temp;

struct stu_node{
    int xb;
    int flag;
    struct stu_node * next;
};
struct stu_node * create(int x);
void go_through(struct stu_node * head,int * c);

int main()
{
    int count;
    struct stu_node * head = NULL,* p = NULL;
    while(cin>>t)
        while(t--)
        {
            cin>>n>>m;
            count=0;n_temp=1;
            head = create(n);p=head;
            go_through(head, &count);
            for(int i=1;i<=n;i++)
            {
                if(p->flag == 1)
                {
                    cout<<p->xb<<endl;
                    break;
                }
                else
                    p = p->next;
            }
        }
    return 0;
}

struct stu_node * create(int x)
{
    struct stu_node * head = NULL,*p=NULL,*q=NULL;
    int i,size=sizeof(struct stu_node);

    q = (struct stu_node *) malloc (size);
    q->xb = 1;q->flag = 1;p = q;
    head = q;
    for(i=2;i<=x;i++)
    {
        p = (struct stu_node *) malloc (size);
        p->xb = i;p->flag = 1;
        q->next = p;
        q = p;
    }
    p->next = NULL;

    return head;
}

void go_through(struct stu_node * head,int * c)
{
    int i;
    struct stu_node * p = NULL;
    p = head;
    while(n_temp<n)
    {
        if(p->flag == 1)
            (*c)++;
        if(*c == m)
        {
            p->flag = 0;
            n_temp++;
            *c = 0 ;
        }
        if(p->next != NULL)
            p = p->next;
        else
            p = head;
    }
}

Problem B: 用链表实现登记成绩

Description

叶老师想要用链表登记成绩。对于每张试卷有两个信息:学号和成绩。

对于登记成绩,要求学号小的成绩登记在学号大的成绩之前。

叶老师有两种操作:

1 a b:向链表中加入学号为a成绩为b的同学的成绩,题目保证不同的卷子不会有相同的学号。

2 k : 查询当前链表中第k个同学的成绩是多少,题目保证k小于等于当前链表的长度。

请用链表做这道题!

Input

第一行输入一个整数Q,表示操作的个数。

接下来输入Q行,每一行是(1 a b)或者(2 k)格式,分别表示第一种和第二种操作。

1 <= k, Q <= 1000

1 <= a <= 1000000000

1 <= b <= 100

Output

对于每一个第二个操作,输出一个整数表示第k个同学的成绩。

Sample Input

3
1 20163266 100
1 20163265 99
2 1

Sample Output

99

代码实现

#include<iostream>
#include<cstdlib>
using namespace std;

int q,temp,a,b,k;
struct stu *head = NULL, *tail = NULL, *ptr = NULL, *ptr_temp = NULL;

struct stu{
    int xh;
    int grade;
    struct stu * next;
};
void insert();
void search();

int main()
{
    while(cin>>q)
    {
        head = (struct stu *) malloc (sizeof(struct stu));
        tail = head;
        q--;
        cin>>temp>>a>>b;
        head->xh = a;
        head->grade = b;
        head->next = NULL;
        while(q--)
        {
            cin>>temp;
            if(temp == 1)
            {
                cin>>a>>b;
                insert();
            }
            else if(temp == 2)
            {
                cin>>k;
                search();
            }
        }
    }
    return 0;
}

void insert()
{
    ptr = (struct stu *) malloc (sizeof(struct stu));
    if(a < head->xh)
    {
       ptr->next = head;
       head = ptr;
    }
    else if(a > tail->xh)
    {
        tail->next = ptr;
        ptr->next = NULL;
        tail = ptr;
    }
    else
    {
        ptr_temp = head;
        while(a > ptr_temp->xh)
        {
            if(a < ptr_temp->next->xh)
            {
                ptr->next = ptr_temp->next;
                ptr_temp->next = ptr;
                break;
            }
            ptr_temp = ptr_temp->next;
        }
    }
    ptr->xh = a;
    ptr->grade = b;
}

void search()
{
    ptr = head;
    for(int i=1;i<k;i++)
        ptr = ptr->next;
    cout<<ptr->grade<<endl;
}

说几句

之前没有进行过这样地链表训练
今天这两题也是敲了很久
刚开始是看着书里地内容
但是大部分都是一下快一小块的模块化的代码 只给出一小部分 虽然能看懂 但是对自己编程的帮助不是特别大
我觉得学习最快的那是 看一整篇完整的代码

总结

emmm
老是懒得free掉开辟的内存 这是一个不好的习惯
emmm
与其说懒得free 不如说 不知道怎么快速地free掉 暂时想的还是一步一步过去一步一步free
malloc 是在 stdlib.h 头文件里的
这两题写的时候都没加头文件 但是神奇地可以正常运行 所以这两题交上去都CE了一次
链表的题只要一步一步跟着思路走下去 感觉模块化地写 很耗时间 但是正确率超乎我想象 原以为要找bug找好久的 但是两个都直接出正确结果
总的来说还是要理清思路

发布了149 篇原创文章 · 获赞 14 · 访问量 8991

猜你喜欢

转载自blog.csdn.net/weixin_45485719/article/details/103624789