3月14日OJ刷题

基于链表的两个递增有序序列的合并

描述

给定两个递增的整数序列A和B,利用链表表示序列A和B,将A和B合并为一个递增的有序序列C,序列C不允许有重复的数据。要求空间复杂度为O(1)。

输入

多组数据,每组数据有三行,第一行为序列A和B的长度n和m,第二行为序列A的n个元素,第三行为序列B的m个元素(元素之间用空格分隔)。n=0且m=0时输入结束。

输出

对于每组数据输出一行,为合并后的序列,每个数据之间用空格分隔。

输入样例 1 

5 5
1 3 5 7 9 
2 4 6 8 10 
3 4
1 5 9
1 2 5 9
0 0

输出样例 1

1 2 3 4 5 6 7 8 9 10
1 2 5 9
#include<bits/stdc++.h>
using namespace std;
typedef struct LNode
{
    int data;
    LNode *next;
}LNode,*LinkList;

void TailCreate(LinkList &l,int n)
{
    l=new LNode;
    l->next=NULL;
    LNode *s,*r=l;
    for(int i=0;i<n;i++)
    {
        int x;
        cin>>x;
        s=new LNode;
        s->data=x;
        r->next=s;
        r=s;
    }
    r->next=NULL;
}

void print(LinkList l)
{
    LNode *p=l->next;
    while(p!=NULL)
    {
        cout<<p->data;
        if(p->next)
        {
            cout<<" ";
        }
        p=p->next;
    }
    cout<<endl;
}

void Merge(LinkList &la,LinkList &lb)
{
    LinkList lc=new LNode;
    lc->next=NULL;
    LNode *pa=la->next,*pb=lb->next,*pc=lc;
    while(pa!=NULL&&pb!=NULL)
    {
        if(pa->data<pb->data)
        {
            pc->next=pa;
            pc=pa;
            pa=pa->next;
        }
        else if(pa->data>pb->data)
        {
            pc->next=pb;
            pc=pb;
            pb=pb->next;
        }
        else
        {
            pc->next=pa;
            pc=pa;
            pa=pa->next;
            pb=pb->next;
        }
    }
    pc->next=pa?pa:pb;
    print(lc);
}

int main()
{
    int n,m;
    cin>>n>>m;
    while(n!=0&&m!=0)
    {
        LinkList la,lb;
        TailCreate(la,n);
        TailCreate(lb,m);
        Merge(la,lb);
        cin>>n>>m;
    }
}

 基于链表的两个非递减有序序列的合并

描述

给定两个非递减的整数序列A和B,利用链表表示序列A和B,将A和B合并为一个非递增的有序序列C,序列C允许有重复的数据。要求空间复杂度为O(1)。

输入

多组数据,每组数据有三行,第一行为序列A和B的长度n和m,第二行为序列A的n个元素,第三行为序列B的m个元素(元素之间用空格分隔)。n=0且m=0时输入结束。

输出

对于每组数据输出一行,为合并后的序列,每个数据之间用空格分隔。

输入样例 1 

5 5
1 3 5 7 9
2 4 6 8 10
5 6
1 2 2 3 5
2 4 6 8 10 12
0 0

输出样例 1

10 9 8 7 6 5 4 3 2 1
12 10 8 6 5 4 3 2 2 2 1
#include<bits/stdc++.h>
using namespace std;
typedef struct LNode
{
    int data;
    LNode *next;
}LNode,*LinkList;

void HeadCreate(LinkList &l,int n)
{
    l=new LNode;
    l->next=NULL;
    LNode *s;
    for(int i=0;i<n;i++)
    {
        int x;
        cin>>x;
        s=new LNode;
        s->data=x;
        s->next=l->next;
        l->next=s;
    }
}

void print(LinkList l)
{
    LNode *p=l->next;
    while(p!=NULL)
    {
        cout<<p->data;
        if(p->next)
        {
            cout<<" ";
        }
        p=p->next;
    }
    cout<<endl;
}

void Merge(LinkList &la,LinkList &lb)
{
    LinkList lc=new LNode;
    lc->next=NULL;
    LNode *pa=la->next,*pb=lb->next,*pc=lc;
    while(pa!=NULL&&pb!=NULL)
    {
        if(pa->data>pb->data)
        {
            pc->next=pa;
            pc=pa;
            pa=pa->next;
        }
        else
        {
            pc->next=pb;
            pc=pb;
            pb=pb->next;
        }
    }
    pc->next=pa?pa:pb;
    print(lc);
}

int main()
{
    int n,m;
    cin>>n>>m;
    while(n!=0&&m!=0)
    {
        LinkList la,lb;
        HeadCreate(la,n);
        HeadCreate(lb,m);
        Merge(la,lb);
        cin>>n>>m;
    }
}

基于链表的两个集合的交集

描述

给定两个递增的整数集合A和B,分别用链表表示集合A和B,求出A和B的交集,并存放在A中。要求空间复杂度为O(1)。

输入

多组数据,每组数据有三行,第一行为序列A和B的长度n和m,第二行为序列A的n个元素,第三行为序列B的m个元素(元素之间用空格分隔)。n=0且m=0时输入结束。

输出

对于每组数据输出一行,为A和B的交集,每个数据之间用空格分隔。

输入样例 1 

5 5
1 3 5 7 9
1 2 3 4 5
3 4
1 2 5
2 4 5 6
0 0

输出样例 1

1 3 5
2 5

 

#include<bits/stdc++.h>
using namespace std;
typedef struct LNode
{
    int data;
    LNode *next;
}LNode,*LinkList;

void TailCreate(LinkList &l,int n)
{
    l=new LNode;
    l->next=NULL;
    LNode *s,*r=l;
    for(int i=0;i<n;i++)
    {
        int x;
        cin>>x;
        s=new LNode;
        s->data=x;
        r->next=s;
        r=s;
    }
    r->next=NULL;
}

void print(LinkList l)
{
    LNode *p=l->next;
    while(p!=NULL)
    {
        cout<<p->data;
        if(p->next)
        {
            cout<<" ";
        }
        p=p->next;
    }
    cout<<endl;
}

void Jiao(LinkList &la,LinkList &lb)
{
    LNode *pa=la->next,*pb=lb->next,*pc=la;
    while(pa!=NULL&&pb!=NULL)
    {
       if(pa->data==pb->data)
       {
           pc->next=pb;
           pc=pb;
           pa=pa->next;
           pb=pb->next;
       }
       else if(pa->data<pb->data)
       {
           pa=pa->next;
       }
       else
       {
           pb=pb->next;
       }
    }
    pc->next=NULL;
    print(la);
}

int main()
{
    int n,m;
    cin>>n>>m;
    while(n!=0&&m!=0)
    {
        LinkList la,lb;
        TailCreate(la,n);
        TailCreate(lb,m);
        Jiao(la,lb);
        cin>>n>>m;
    }
}

基于链表的两个集合的差集

描述

给定两个递增的整数集合,分别用链表A和B表示,求出A和B的差集(即仅由在A中出现而不在B中出现的元素所构成的集合),并以同样的形式存储,同时返回该集合的元素个数。要求空间复杂度为O(1)。

输入

多组数据,每组数据有三行,第一行为序列A和B的长度n和m,第二行为序列A的n个元素,第三行为序列B的m个元素(元素之间用空格分隔)。n=0且m=0时输入结束。

输出

对于每组数据输出两行,第一行是A和B的差集,第二行为差集中的元素个数,每个数据之间用空格分隔。

输入样例 1 

5 5
1 3 5 7 9
1 2 3 4 5
3 4
1 2 6
2 4 5 7
0 0

输出样例 1

7 9
2
1 6
2

 

#include<bits/stdc++.h>
using namespace std;
typedef struct LNode
{
    int data;
    LNode *next;
}LNode,*LinkList;

void TailCreate(LinkList &l,int n)
{
    l=new LNode;
    l->next=NULL;
    LNode *s,*r=l;
    for(int i=0;i<n;i++)
    {
        int x;
        cin>>x;
        s=new LNode;
        s->data=x;
        r->next=s;
        r=s;
    }
    r->next=NULL;
}

void print(LinkList l)
{
    LNode *p=l->next;
    while(p!=NULL)
    {
        cout<<p->data;
        if(p->next)
        {
            cout<<" ";
        }
        p=p->next;
    }
    cout<<endl;
}

void Length(LinkList l)
{
    LNode *p=l->next;
    int length=0;
    while(p!=NULL)
    {
        length++;
        p=p->next;
    }
    cout<<length<<endl;
}

void Jiao(LinkList &la,LinkList &lb)
{
    LNode *pa=la->next,*pb=lb->next,*pc=la;
    while(pa!=NULL&&pb!=NULL)
    {
       if(pa->data==pb->data)
       {
           pa=pa->next;
           pb=pb->next;
       }
       else if(pa->data>pb->data)
       {
           pb=pb->next;
       }
       else if(pa->data<pb->data)
       {
           pc->next=pa;
           pc=pa;
           pa=pa->next;
       }
    }
    if(pb==NULL)
    {
        pc->next=pa;
    }
    print(la);
    Length(la);
}

int main()
{
    int n,m;
    cin>>n>>m;
    while(n!=0&&m!=0)
    {
        LinkList la,lb;
        TailCreate(la,n);
        TailCreate(lb,m);
        Jiao(la,lb);
        cin>>n>>m;
    }
}

 

链表的分解

描述

利用单链表A表示一个非零整数序列,把A分解为两个具有相同结构的链表B和C,其中B表的结点为A表中值小于零的结点,而C表的结点为A表中值大于零的结点。要求空间复杂度为O(1),链表B和C均利用链表A的结点空间。

输入

多组数据,每组数据有两行,第一行为链表A的长度n,第二行为链表A的n个元素(元素之间用空格分隔)。当n=0时输入结束。

输出

对于每组数据分别输出两行,分别对应链表B和C的元素,每个数据之间用空格分隔。

输入样例 1 

7
3 -6 1 -2 4 -3 8
8
2 5 3 -1 -2 2 6 -1
0

输出样例 1

-6 -2 -3
3 1 4 8
-1 -2 -1
2 5 3 2 6
#include<bits/stdc++.h>
using namespace std;
typedef struct LNode
{
    int data;
    LNode *next;
}LNode,*LinkList;

void TailCreate(LinkList &l,int n)
{
    l=new LNode;
    l->next=NULL;
    LNode *s,*r=l;
    for(int i=0;i<n;i++)
    {
        int x;
        cin>>x;
        s=new LNode;
        s->data=x;
        r->next=s;
        r=s;
    }
    r->next=NULL;
}

void print(LinkList l)
{
    LNode *p=l->next;
    while(p!=NULL)
    {
        cout<<p->data;
        if(p->next)
        {
            cout<<" ";
        }
        p=p->next;
    }
    cout<<endl;
}


void Divid(LinkList &l)
{
    LinkList la=new LNode;
    la->next=NULL;
    LinkList lb=new LNode;
    lb->next=NULL;
    LNode *p=l->next,*pa=la,*pb=lb;
    while(p!=NULL)
    {
        if(p->data<0)
        {
            pa->next=p;
            pa=p;
            p=p->next;
        }
        else if(p->data>0)
        {
            pb->next=p;
            pb=p;
            p=p->next;
        }
    }
    pa->next=NULL;
    pb->next=NULL;
    print(la);
    print(lb);
}

int main()
{
    int n;
    while(cin>>n&&n!=0)
    {
        LinkList l;
        TailCreate(l,n);
        Divid(l);
    }
}

 查找链表中的最大值

描述

利用单链表表示一个整数序列,通过一趟遍历在单链表中确定值最大的结点。

输入

多组数据,每组数据有两行,第一行为链表的长度n,第二行为链表的n个元素(元素之间用空格分隔)。当n=0时输入结束。

输出

对于每组数据分别输出一行,输出每个链表的最大值。

输入样例 1 

5
2 1 3 5 4
6
2 3 10 4 5 1
4
-1 -2 -3 -4
0

输出样例 1

5
10
-1
#include<bits/stdc++.h>
using namespace std;
typedef struct LNode
{
    int data;
    LNode *next;
}LNode,*LinkList;

void TailCreate(LinkList &l,int n)
{
    l=new LNode;
    l->next=NULL;
    LNode *s,*r=l;
    for(int i=0;i<n;i++)
    {
        int x;
        cin>>x;
        s=new LNode;
        s->data=x;
        r->next=s;
        r=s;
    }
    r->next=NULL;
}

void print(LinkList l)
{
    LNode *p=l->next;
    while(p!=NULL)
    {
        cout<<p->data;
        if(p->next)
        {
            cout<<" ";
        }
        p=p->next;
    }
    cout<<endl;
}


void FindMax(LinkList &l)
{
    LNode *p=l->next;
    int maxx=p->data;
    while(p!=NULL)
    {
        if(p->data>maxx)
        {
            maxx=p->data;
        }
        p=p->next;
    }
    cout<<maxx<<endl;
}

int main()
{
    int n;
    while(cin>>n&&n!=0)
    {
        LinkList l;
        TailCreate(l,n);
        FindMax(l);
    }
}

 

链表的逆转

描述

利用单链表表示一个整数序列,通过一趟遍历,将单链表中所有结点的链接方向逆转。要求空间复杂度为O(1)。

输入

多组数据,每组数据有两行,第一行为链表的长度n,第二行为链表的n个元素(元素之间用空格分隔)。当n=0时输入结束。

输出

对于每组数据分别输出一行,逆序输出链表中的元素,元素之间用空格分隔。

输入样例 1 

5
1 2 3 4 5
6
3 1 2 5 4 6
0

输出样例 1

5 4 3 2 1
6 4 5 2 1 3
#include<bits/stdc++.h>
using namespace std;
typedef struct LNode
{
    int data;
    LNode *next;
}LNode,*LinkList;

void TailCreate(LinkList &l,int n)
{
    l=new LNode;
    l->next=NULL;
    LNode *s,*r=l;
    for(int i=0;i<n;i++)
    {
        int x;
        cin>>x;
        s=new LNode;
        s->data=x;
        r->next=s;
        r=s;
    }
    r->next=NULL;
}

void print(LinkList l)
{
    LNode *p=l->next;
    while(p!=NULL)
    {
        cout<<p->data;
        if(p->next)
        {
            cout<<" ";
        }
        p=p->next;
    }
    cout<<endl;
}


void Reverse(LinkList &l)
{
    LNode *p=l->next,*r;
    LinkList ll=new LNode;
    ll->next=NULL;
    while(p!=NULL)
    {
        r=p->next;
        p->next=ll->next;
        ll->next=p;
        p=r;
    }
    print(ll);
}

int main()
{
    int n;
    while(cin>>n&&n!=0)
    {
        LinkList l;
        TailCreate(l,n);
        Reverse(l);
    }
}

 

删除链表中满足区间值的结点

描述

利用单链表表示一个递增的整数序列,删除链表中值大于等于mink且小于等于maxk的所有元素(mink和maxk是给定的两个参数,其值可以和表中的元素相同,也可以不同)。

输入

多组数据,每组数据有两行,第一行为链表的长度n,第二行为链表的n个元素(元素之间用空格分隔),第三行为给定的mink和maxk(用空格分隔)。当n=0时输入结束。

输出

对于每组数据分别输出一行,依次输出删除元素后的链表元素,元素之间用空格分隔。

输入样例 1 

5
1 2 3 4 5
2 4
6
2 4 6 8 10 12
3 5
0

输出样例 1

1 5 
2 6 8 10 12
#include<bits/stdc++.h>
using namespace std;
typedef struct LNode
{
    int data;
    LNode *next;
}LNode,*LinkList;

void TailCreate(LinkList &l,int n)
{
    l=new LNode;
    l->next=NULL;
    LNode *s,*r=l;
    for(int i=0;i<n;i++)
    {
        int x;
        cin>>x;
        s=new LNode;
        s->data=x;
        r->next=s;
        r=s;
    }
    r->next=NULL;
}

void print(LinkList l)
{
    LNode *p=l->next;
    while(p!=NULL)
    {
        cout<<p->data;
        if(p->next)
        {
            cout<<" ";
        }
        p=p->next;
    }
    cout<<endl;
}


void Delete(LinkList &l,int mink,int maxk)
{
    LNode *p=l->next,*pre=l;
    while(p!=NULL)
    {
        if(p->data>=mink&&p->data<=maxk)
        {
            pre->next=p->next;
            p=p->next;
        }
        else
        {
            pre=p;
            p=p->next;
        }
    }
    print(l);
}

int main()
{
    int n;
    int mink,maxk;
    while(cin>>n&&n!=0)
    {
        LinkList l;
        TailCreate(l,n);
        cin>>mink>>maxk;
        Delete(l,mink,maxk);
    }
}

 

双向循环链表中结点的交换

描述

利用双向循环链表表示一个整数序列,指定一个结点位置用p指向该结点,交换p所指向的结点及其前驱结点的顺序。

输入

多组数据,每组数据有三行,第一行为链表的长度n,第二行为链表的n个元素(元素之间用空格分隔),第三行为p所指向的结点位置。当n=0时输入结束。

输出

对于每组数据分别输出一行,依次输出交换结点顺序后的链表元素,元素之间用空格分隔。

输入样例 1 

5
44 11 22 33 55
3
6
22 33 11 66 44 55
6
0

输出样例 1

44 22 11 33 55
22 33 11 66 55 44
#include<bits/stdc++.h>
using namespace std;
typedef struct LNode
{
    int data;
    LNode *piror;
    LNode *next;
}LNode,*LinkList;

void Create(LinkList &l,int n)//不能带头节点
{
    l=new LNode;
    int x;
    cin>>x;
    l->data=x;
    l->next=NULL;
    l->piror=NULL;
    LNode *r=l,*s;
    for(int i=1;i<n;i++)
    {
        int x;
        cin>>x;
        s=new LNode;
        s->data=x;
        r->next=s;
        s->piror=r;
        r=s;
    }
    r->next=l;
    l->piror=r;
}

void Exchenge(LinkList &l,int k)
{
    LNode *p=l;
    int i=0;
    while(p&&i<k-1)
    {
        p=p->next;
        i++;
    }
    int temp=p->data;
    p->data=p->piror->data;
    p->piror->data=temp;
}

void print(LinkList l)
{
    LNode *p=l;
    cout<<p->data<<" ";
	p=l->next;
    while(p!=l)//需要注意是p!=l
    {
        cout<<p->data;
        if(p->next!=l)
        {
            cout<<" ";
        }
        p=p->next;
    }
    cout<<endl;
}

int main()
{
    int n;
    while(cin>>n&&n!=0)
    {
        int k;
        LinkList l;
        Create(l,n);
        cin>>k;
        Exchenge(l,k);
        print(l);
    }
}

删除顺序表中指定值的所有元素

描述

利用顺序表表示一个包括n个整数的序列,请实现一个时间复杂度为O(n),空间复杂度为O(1)的算法,该算法可以删除表中所有值为item的元素。

输入

多组数据,每组数据有三行,第一行为顺序表的长度n,第二行为顺序表的n个元素(元素之间用空格分隔),第三行为待删除的元素的值item。当n=0时输入结束。

输出

对于每组数据分别输出一行,依次输出删除值为item的元素后顺序表中的剩余元素,元素之间用空格分隔。

输入样例 1 

5
44 11 22 33 22
11
6
22 33 11 33 33 55
33
0

输出样例 1

44 22 33 22
22 11 55

 

#include<bits/stdc++.h>
using namespace std;
typedef struct
{
    int data[10000];
    int length;
}SqList;

void Create(SqList &l,int n)
{
    l.length=n;
    for(int i=0;i<n;i++)
    {
        cin>>l.data[i];
    }
}

void Print(SqList l)
{
    for(int i=0;i<l.length;i++)
    {
        cout<<l.data[i];
        if(i!=l.length-1)
        {
            cout<<" ";
        }
    }
    cout<<endl;
}

void Delete(SqList &l,int x)
{
    int k=0;
    for(int i=0;i<l.length;i++)
    {
        if(l.data[i]==x)
        {
            k++;
        }
        else
        {
            l.data[i-k]=l.data[i];
        }
    }
    l.length=l.length-k;
}
int main()
{
    int n;
    while(cin>>n&&n!=0)
    {
        SqList l;
        Create(l,n);
        int k;
        cin>>k;
        Delete(l,k);
        Print(l);
    }
}

查找链表中倒数第k个结点

描述

利用单链表表示一个整数序列,请实现一个时间复杂度为O(n)、空间复杂度为O(1)的算法,通过一趟遍历在单链表中确定倒数第k个结点。

输入

多组数据,每组数据有三行,第一行为链表的长度n,第二行为链表的n个元素(元素之间用空格分隔),第三行为k。当n=0时输入结束。

输出

对于每组数据分别输出一行,输出每个链表的倒数第k个结点对应的数值。

输入样例 1 

7
5 2 3 4 50 100 70
3
5
20 30 10 4 5
5
0

输出样例 1

50
20

 

#include<bits/stdc++.h>
using namespace std;
typedef struct LNode
{
    int data;
    LNode *next;
}LNode,*LinkList;

void TailCreate(LinkList &l,int n)
{
    l=new LNode;
    l->next=NULL;
    LNode *s,*r=l;
    for(int i=0;i<n;i++)
    {
        int x;
        cin>>x;
        s=new LNode;
        s->data=x;
        r->next=s;
        r=s;
    }
    r->next=NULL;
}

void print(LinkList l)
{
    LNode *p=l->next;
    while(p!=NULL)
    {
        cout<<p->data;
        if(p->next)
        {
            cout<<" ";
        }
        p=p->next;
    }
    cout<<endl;
}

int Length(LinkList l)
{
    LNode *p=l->next;
    int sum=0;
    while(p!=NULL)
    {
        sum++;
        p=p->next;
    }
    return sum;
}
void Find(LinkList &l,int k)
{
    LNode *p=l->next;
    for(int i=0;i<Length(l)-k;i++)
    {
        p=p->next;
    }
    cout<<p->data<<endl;
}

int main()
{
    int n;
    int k;
    while(cin>>n&&n!=0)
    {
        LinkList l;
        TailCreate(l,n);
        cin>>k;
        Find(l,k);
    }
}

删除链表中绝对值相等的结点

描述

利用单链表表示一个整数序列,实现一个时间复杂度为O(n)的算法,对于链表中绝对值相

等的结点,仅保留第一次出现的结点而删除其余绝对值相等的结点。

例如,若给定的单链表HEAD如下:

删除后的单链表HEAD为:

输入

多组数据,每组数据有两行,第一行为链表的长度n,第二行为链表的n个元素(元素之间用空格分隔)。当n=0时输入结束。

输出

对于每组数据分别输出一行,依次输出删除结点后的链表元素,元素之间用空格分隔。

输入样例 1 

5
21 -15 -15 -7 15
7
90 32 -90 -66 77 66 90
0

输出样例 1

21 -15 -7
90 32 -66 77

 

#include<bits/stdc++.h>
using namespace std;
typedef struct LNode
{
    int data;
    LNode *next;
}LNode,*LinkList;

void TailCreate(LinkList &l,int n)
{
    l=new LNode;
    l->next=NULL;
    LNode *s,*r=l;
    for(int i=0;i<n;i++)
    {
        int x;
        cin>>x;
        s=new LNode;
        s->data=x;
        r->next=s;
        r=s;
    }
    r->next=NULL;
}

void print(LinkList l)
{
    LNode *p=l->next;
    while(p!=NULL)
    {
        cout<<p->data;
        if(p->next)
        {
            cout<<" ";
        }
        p=p->next;
    }
    cout<<endl;
}

int Length(LinkList l)
{
    LNode *p=l->next;
    int sum=0;
    while(p!=NULL)
    {
        sum++;
        p=p->next;
    }
    return sum;
}
void Delete(LinkList &l)
{
    int flag[10000];
    memset(flag,0,sizeof(flag));
    LNode *p=l->next,*pre=l;
    while(p!=NULL)
    {
        if(flag[abs(p->data)]==0)
        {
            flag[abs(p->data)]=1;
            pre=p;
            p=p->next;
        }
        if(flag[abs(p->data)]==1)
        {
            pre->next=p->next;
            p=p->next;
        }
    }
    print(l);
}

int main()
{
    int n;
    int k;
    while(cin>>n&&n!=0)
    {
        LinkList l;
        TailCreate(l,n);
        Delete(l);
    }
}

求解两个升序序列的中位数

描述

一个长度为L(L≥1)的升序序列S,处在第L/2(若为小数则去掉小数后加1)个位置的数称为S的中位数。例如,若序列S1=(11,13,15,17,19),则S1的中位数是15。两个序列的中位数是含它们所有元素的升序序列的中位数。例如,若S2=(2,4,6,8,20),则S1和S2的中位数是11。现有两个等长升序序列A和B,试实现一个在时间和空间两方面都尽可能高效的算法,找出两个序列A和B的中位数。

输入

多组数据,每组数据有三行,第一行为序列的长度n,第二行为序列A的n个元素,第三行为序列B的n个元素(元素之间用空格分隔)。当n=0时输入结束。

输出

对于每组数据分别输出两个序列的中位数,占一行。

输入样例 1 

5
11 13 15 17 19 
2 4 6 8 20
6
1 2 3 4 5 6
7 8 9 10 11 12
0

输出样例 1

11
6

 

#include<bits/stdc++.h>
using namespace std;
int Find(int a[],int b[],int n)
{
    int s1=0,d1=n-1,m1;
    int s2=0,d2=n-1,m2;
    while(s1!=d1||s2!=d2)
    {
        m1=(s1+d1)/2;
        m2=(s2+d2)/2;
        if(a[m1]==b[m2])
        {
            return a[m1];
        }
        if(a[m1]<b[m2])
        {
            if((s1+d1)%2==0)
            {
                s1=m1;
                d2=m2;
            }
            else
            {
                s1=m1+1;
                d2=m2;
            }
        }
        else
        {
            if((s1+d1)%2==0)
            {
                d1=m1;
                s2=m2;
            }
            else
            {
                d1=m1;
                s2=m2+1;
            }
        }
    }
    return a[s1]<b[s2]?a[s1]:b[s2];
}
int main()
{
    int n;
    int a[10000];
    int b[10000];
    while(cin>>n&&n!=0)
    {
        for(int i=0;i<n;i++)
        {
            cin>>a[i];
        }
        for(int j=0;j<n;j++)
        {
            cin>>b[j];
        }
        cout<<Find(a,b,n)<<endl;
    }
}

查找两个单词链表共同后缀的起始结点

描述

假定采用带头结点的单链表保存单词,当两个单词有相同的后缀时,则可共享相同的后缀空间。例如,“loading”和“being”的存储映像如下图所示:

设str1和str2分别指向两个单词所在单链表的头结点,请实现一个时间上尽可能高效的算法,找出由str1和str2所指的两个链表共同后缀的起始位置的结点,输出该结点对应的字符(如图中的字符i)。

输入

多组数据,每组数据有三行,第一行为链表str1和str2的长度n和m,第二行为链表str1的n个元素,第三行为链表str2的m个元素(元素之间用空格分隔)。n=0且m=0时输入结束。

输出

对于每组数据输出一行,为共同后缀的起始位置结点对应的字符。

输入样例 1 

7 5
l o a d i n g
b e i n g
7 9
f l u e n c y
f r e q u e n c y
0 0

输出样例 1

i
u

 

#include<bits/stdc++.h>
using namespace std;
typedef struct LNode
{
    char data;
    LNode *next;
}LNode,*LinkList;

void TailCreate(LinkList &l,int n)
{
    l=new LNode;
    l->next=NULL;
    LNode *s,*r=l;
    for(int i=0;i<n;i++)
    {
        char x;
        cin>>x;
        s=new LNode;
        s->data=x;
        r->next=s;
        r=s;
    }
    r->next=NULL;
}

void print(LinkList l)
{
    LNode *p=l->next;
    while(p!=NULL)
    {
        cout<<p->data;
        if(p->next)
        {
            cout<<" ";
        }
        p=p->next;
    }
    cout<<endl;
}


void Find(LinkList la,LinkList lb,int m,int n)
{
    LNode *p=la->next,*q=lb->next;
    while(m>n)
    {
        p=p->next;
        m--;
    }
    while(n>m)
    {
        q=q->next;
        n--;
    }
    while(p!=NULL&&q!=NULL)
    {
        if(p->data!=q->data)
        {
            p=p->next;
            q=q->next;
        }
        else
        {
            cout<<p->data<<endl;
            return;
        }
    }
}

int main()
{
    int n,m;
    while(cin>>n>>m&&n!=0&&m!=0)
    {
        LinkList la,lb;
        TailCreate(la,n);
        TailCreate(lb,m);
        Find(la,lb,n,m);
    }
}

 

猴子选大王问题

描述

一堆猴子都有编号,编号是1,2,3 ...m,这群猴子(m个)按照1~m的顺序围坐一圈,从第1开始数,每数到第n个,该猴子就要离开此圈,这样依次下来,直到圈中只剩下最后一只猴子,则该猴子为大王。利用单向循环链表模拟此过程,依次输出出圈的猴子编号。

输入

多组数据,每组数据占一行,包括两个数据m和n。m代表猴子个数,n代表步数,m=0且n=0时输入结束。

输出

依次输出出圈的猴子编号,编号之间用空格隔开。

输入样例 1 

10 4
8 3
0 0

输出样例 1

4 8 2 7 3 10 9 1 6 5
3 6 1 5 2 8 4 7

 

#include<bits/stdc++.h>
using namespace std;
typedef struct LNode
{
    int data;
    LNode *next;
}LNode,*LinkList;

void Create(LinkList &l,int n)
{
    l=new LNode;
    l->data=1;
    l->next=NULL;
    LNode *r=l,*s;
    for(int i=2;i<=n;i++)
    {
        s=new LNode;
        s->data=i;
        r->next=s;
        r=s;
    }
    r->next=l;
    l=r;//l一开始必须指向尾节点
}

void print(LinkList &l,int k)
{
    while(l->next!=l)
    {
        for(int i=1;i<k;i++)
        {
            l=l->next;
        }
        LNode *p=l->next;
        cout<<p->data<<" ";
        l->next=p->next;
    }
    cout<<l->data<<endl;
}

int main()
{
    int n;
    int k;
    while(cin>>n>>k&&n!=0&&k!=0)
    {
        LinkList l;
        Create(l,n);
        print(l,k);
    }
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值