sdut-oj-4205-寻找关键点

Description
现定义关键点为一条链中处于中间位置的节点,例如 1 3 4中,3就是这个整数链中的关键点。

现在小玉得到了一个整数链,确保链中的各个数都互不相同且数列中数的个数为奇数。

可是,由于小玉的一些特殊要求,她可能会对这个链进行一些特别的操作。

操作 1 :给定两个数a和b,每次删除链中值为a和值为b两个节点。
操作 2 :给定两个数a和b,每次在链中值为1的节点后插入a,在链中值为2的节点后插入b。
由于小玉特殊的要求,她保证链中肯定会有值为1和2的节点,并且这两个节点永远不会被删除。保证在插入操作之后链中始终不会有重复值的节点。

现在请你写出一个程序,帮助小玉找出链中的关键点。

Input
只有一组数据

先输入一个整数n(10<=n<=100000),且保证n一定为奇数

接下来输入n个互不相同的整数num(1<=num<=10000000)

接着下一行输入一个整数m(1<=m<=4000)

代表接下来有m行

每行有3个数aa,bb,cc. 其中第一个数aa表示操作类型,aa为1代表删除链中值为bb和cc的数,

aa为2代表在链中值为1的节点后增加值为bb的节点,在链中值为2的节点后增加值为cc的节点。

(保证删除的节点在链中一定有,保证插入的节点与链中已有节点不会重复)

Output
对于每次操作,输出一个值h,代表操作完成后链中的关键点。

Sample
Input
5
1 3 4 5 2
2
1 3 4
2 3 4
Output
5
5

#include<bits/stdc++.h>

using namespace std;

int n;

typedef struct node
{
    int data;
    struct node *next;
} List;

List *creat(int n)
{
    List *head, *tail, *p;
    head = new List;
    head->next = NULL;
    tail = head;
    for(int i = 0; i < n; i++)
    {
        p = new List;
        scanf("%d", &p->data);
        p->next = NULL;
        tail->next = p;
        tail = p;
    }
    return head;
}

void List_one(List *head, int a, int b)
{
    List *p, *q;
    p = head;
    q = head->next;
    while(q->next)//删除某一元素,都是找到他的前一个元素
    {
        if(q->data == a)
        {
            p->next = q->next;
            free(q);
            q = p->next;
            n--;
        }
        else if(q->data == b)
        {
            p->next = q->next;
            free(q);
            q = p->next;
            n--;
        }
        else//没有相匹配的,往下移动
        {
            p = q;
            q = q->next;
        }
    }
    if(q->next == NULL)//进行特判,判断是否要删除的结点位于表尾
    {
        if(q->data == a)
        {
            p->next = q->next;
            free(q);
            n--;
        }
        else if(q->data == b)
        {
            p->next = q->next;
            free(q);
            n--;
        }
    }
}

void List_two(List *head, int a, int b)
{
    List *p, *q;
    p = head->next;
    while(p)//注意与删除操作不的不同点
    {
        if(p->data == 1)
        {
            q = new List;
            q->data = a;
            q->next = p->next;
            p->next = q;
            n++;
        }
        if(p->data == 2)
        {
            q = new List;
            q->data = b;
            q->next = p->next;
            p->next = q;
            n++;
        }
        p = p->next;
    }
}

int findkey(List *head, int n)//基操,不多解释
{
    List *p;
    int m, k;
    m = n / 2 + 1;
    p = head->next;
    k = 1;
    while(k != m)
    {
        p = p->next;
        k++;
    }
    return p->data;
}

int main()
{
    int a, b, m, num, key;
    List *head;
    scanf("%d", &n);
    head = creat(n);
    scanf("%d", &m);
    while(m--)
    {
        scanf("%d%d%d", &num, &a, &b);
        if(num == 1)
        {
            List_one(head, a, b);
        }
        else
        {
            List_two(head, a, b);
        }
        key = findkey(head, n);
        printf("%d\n", key);
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值