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找好久的 但是兩個都直接出正確結果
總的來說還是要理清思路

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章