PPOJ刷题-1

Posted Mr.wu123

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PPOJ刷题-1相关的知识,希望对你有一定的参考价值。

PPOJ刷题-1

1213:顺序表的删除

题目描述

从顺序表L中删除具有最小值的元素(假设唯一)并友函数返回被删元素的值。空出的元素由最后一个元素填补。

输入

输入包含一个整数n代表顺序表L长度。
接下来包含n个整数,代表顺序表L中的元素。

输出

若顺序表为空,输出 “error”.
若不为空,输出最小元素的值并输出删除最小值之后的顺序表。

样例输入

3
1 2 3

样例输出

1
3 2
#include<bits/stdc++.h>
using namespace std;

bool Del_Min(int *L,int n,int& x)
    if(n==0)
        return false;
    int pos=0;
    x=L[0];
    for(int i=1;i<n;i++)
        if(L[i]<x)
            pos=i;
            x=L[i];
        
    
    L[pos]=L[n-1];
    return true;


int main()

    int n;
    cin>>n;
    int L[100];
    for(int i=0;i<n;i++)
        cin>>L[i];
    
    int Min;
    if(Del_Min(L,n,Min))
        cout<<Min<<endl;
        for(int i=0;i<n-1;i++)//链表中个数减一
            printf("%d ",L[i]);
        printf("\\n");
    else
        cout<<"error"<<endl;
    
    return 0;

1228: 顺序表的删除I

题目描述

长度为n的顺序表L,编写一个时间复杂度为O(n),空间复杂度为O(1)的算法,删除线性表中所有值为x的数据元素。

输入

输入包含一个整数n代表顺序表L长度,一个x代表要删除的元素。
接下来包含n个整数,代表顺序表L中的元素。

输出

输出删除元素x后的顺序表。

样例输入

5 2
1 3 2 5 2

样例输出

1 3 5
#include<bits/stdc++.h>
using namespace std;
const int MaxSize=500;
typedef int ElemType;
struct Sqlist
   ElemType data[MaxSize];
   int length;
;

void Del(Sqlist &L,ElemType 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];//将值不等于x的数往前移
        
    
    L.length-=k;


void Print(Sqlist &L)

    for(int i=0;i<L.length;i++)
        printf("%d ",L.data[i]);
    
    printf("\\n");


int main()

    Sqlist L;
    int n,x;
    cin>>n>>x;
    for(int i=0;i<n;i++)
        cin>>L.data[i];
    
    L.length=n;
    Del(L,x);
    Print(L);
    return 0;

1214: 逆置顺序表

题目描述

PIPI现在由一个顺序表L,他想把顺序表所有元素逆置,要求除了存储L的空间外,辅助的空间复杂度为O(1).

输入

输入包含一个整数n代表顺序表L长度。
接下来包含n个整数,代表顺序表L中的元素。

输出

输出逆置后的顺序表

样例输入

3
1 2 3

样例输出

3 2 1
#include<bits/stdc++.h>
using namespace std;

void Print(int *L,int n)

    for(int i=0;i<n;i++)
        printf("%d ",L[i]);
    
    printf("\\n");


void Reverse(int *L,int n)

    for(int i=0;i<n/2;i++)
        swap(L[i],L[n-i-1]);
    
    Print(L,n);


int main()

    int n;
    cin>>n;
    int L[100];
    for(int i=0;i<n;i++)
        cin>>L[i];
    
    Reverse(L,n);
    return 0;

1544: 删除链表绝对值相同的元素

题目描述

给定一个单链表,请你删除其中绝对值相同的结点,只保留出现第一次的结点。
链表中的元素的绝对值小于10000。

输入

输入一行数据,以EOF结束,代表一个单链表。

输出

输出删除多余的绝对值相同的元素后的链表

样例输入

2 4 -2 3 1 -3

样例输出

2 4 3 1

提示

此题是为了锻炼大家对链表算法的熟悉程度,请大家用链表来完成

#include<bits/stdc++.h>
using namespace std;

typedef struct node

    int val;
    node *next;
*List;

bool vis[10010];//标记数组

void DelSame(List &L)//

    List p = L->next,q = L;
    L->next = NULL;
    while(p)
        List r = p->next;
        if(!vis[abs(p->val)])
            p->next = NULL;//断开P节点
            q->next = p;
            q = p;
            vis[abs(p->val)]=1;
        
        p = r;
    


int main()

    List head = new node(),p = head;//定义链表
    int x;
    while(cin>>x)
        List s = new node();
        s->val = x;
        s->next = NULL;
        p->next = s;
        p = s;//尾插法
    
    DelSame(head);
    p = head->next;
    while(p)
        printf("%d ",p->val);
        p = p->next;
    
    printf("\\n");
    return 0;

1267: 删除单链表的倒数第K个节点

题目描述

给定一个长度为n的单链表,删除倒数第K的节点,然后从头到尾输出每个节点的值。

输入

第一行包含两个整数N,k,k<=N.
第二行包含N个整数,代表从表头到表尾每个节点的值。
你需要建立单链表把这N个数串起来~

输出

按顺序输出删除了倒数第K个节点后每个节点的值。

样例输入

5 2
1 2 3 4 5

样例输出

1 2 3 5
#include<bits/stdc++.h>
using namespace std;

typedef struct node
   node *next;
   int val;
   node()next=NULL;
;

int main()

    int n,k,v;
    cin>>n>>k;
    node *head=new node(),*p=head;
    for(int i=1;i<=n;i++)
        cin>>v;
        p->val=v;
        if(i!=n)
            p->next=new node;
            p=p->next;
        
    
    p=head;
    k=n-k+1;
    if(k==1)//如果是第一个节点
        node *q=head;
        head=head->next;
        delete q;//删除第一个节点
    
    p=head;
    int cnt=1;
    while(p)
        printf("%d ",p->val);
        if(cnt==k-1)
            node *q=p->next;
            p->next=q->next;
            delete q;
        
        p=p->next;
        cnt++;
    
    delete head;//释放节点,节省空间
    return 0;

1271: 反转链表

题目描述

反转长度为N的单链表从位置 LR 的子段。请在常数空间复杂度下使用一趟扫描完成反转。

输入

第一行三个整数N,L,R,1<=L<=R<=N
接下来N个数表示N个节点的值

输出

输出反转后的单链表节点值

样例输入

5 2 4
1 2 3 4 5

样例输出

1 4 3 2 5
#include<bits/stdc++.h>
using namespace std;
typedef struct node
    node *next;
    int val;
    node()
    node(int x) :val(x),next(NULL) 
;

node* reverseBetween(node *head,int m,int n)

    node *preL=NULL,*L=NULL,*sufR=NULL,*H=new node,*q;
    //preL指向第m个节点前一个节点,L指向第m个节点,sufR指向第n个节点的后一个节点
    int c=1,flag=0;
    if(m==1)
        flag=1;
    for(node *p=head;p;c++)
        if(c==m-1) preL=p;
        else if(c==m)
            L=p;
            flag=1;
        
        else if(c==n+1)
            sufR=p;
            flag=0;
        
        if(flag)//使用头插法 放到H为头指针的链表上
            q=p->next;
            p->next=H->next;
            H->next=p;
            p=q;
        else p=p->next;
    
    L->next=sufR;
    if(preL)
        preL->next=H->next;
        return head;
    else
        return H->next;
    


void print(node *x)
    printf("%d ",x->val);
    if(x->next) print(x->next);


int main()

    int n,L,R,v;
    cin>>n>>L>>R;
    node *head=new node,*p=head;
    for(int i=1;i<=n;i++)
        cin>>v;
        p->next=new node(v);
        p=p->next;
    
    print(reverseBetween(head->next,L,R));
    return 0;

1275: 约瑟夫环

解析:

使用循环双向链表来模拟这一过程,设置p指针一开始这项编号为1的节点,每一动m-1次,输出该节点的编号病删去,知道全部节点都删去。

题目描述

N个人坐成一个圆环(编号为1 - N),从第1个人开始报数,数到K的人出列,后面的人重新从1开始报数。问最后剩下的人的编号。
例如:N = 3,K = 2。2号先出列,然后是1号,最后剩下的是3号。

输入

2个数N和K,表示N个人,数到K出列。(2 <= N <= 100, 2 <= K <= 100)

输出

最后剩下的人的编号

样例输入

3 2

样例输出

3
#include<bits/stdc++.h>
using namespace std;
typedef struct node
    node *pre,*next;//前驱,后继
    int id;//编号
    node(int id):id(id)
;
int main()

    int n,m;
    cin>>n>>m;
    node *head=new node(1),*last=head,*now;//不带头结点
    for(int i=2;i<=n;i++)
        now=new node(i);//now指向创建的新节点
        now->pre=last;
        last->next=now;
        last=now;
    
    head->pre=last;//将最后一个节点与第一个节点相联系起来
    last->next=head;
    node *p=head;//通过p节点来移动输出和删除节点
    while(p->next!=p)
        for(int i=0;i<m-1;i++)
            p=p->next;
        
        now=p->next;
        p->pre->next=now;//删除p的过程
        p->next->pre=p->pre;
        p=now;//将p赋值成now
    
    printf("%d\\n",now->id);//输出最后
    return 0;

1294: 多项式加法

解析:

输入时,按照指针大小顺序升序排成一个单链表,然后利用归并排序的思想将两个单链表相加。

题目描述

PIPI有两个多项式PA和PB,现在告诉你两个多项式的项数、每项的系数以及指数,现在它想知道两个多项式相加的结果,请你帮帮它!

输入

单组输入。
第一行两个整数n,m,分别表示PA、PB的项数。0<=n,m<=1000.
接下来n行,描述PA的各项,每行两个整数a,b,a为该项的指数,b为系数,即bxa
接下来m行,描述PB的各项,每行两个整数a,b,a为该项的指数,b为系数,即bxa
其中0<=a,b<=100000.
注意给出的每项指数可能相等。

输出

按指数从小到大输出PA+PB中系数不为0的每项。每行两个整数a,b,a为指数,b为系数。

样例输入

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

样例输出

0 10
1 4
2 5
3 6
#include<bits/stdc++.h>
using namespace std;
typedef struct node
    int b,a;
    node *next;
LNode,*poly;

void init(poly &La,poly &Lb)

    La=new LNode;
    Lb=new LNode;
    La->next=NULL;
    Lb->next=NULL;
    int m,n,a,b;
    cin>>m>>n;
    for(int i=0;i<m;i++)
        cin>>a>>b;
        poly p=new LNode;
        p->next=NULL;
        p->a=a;
        p->b=b;
        poly L=La;//L指向头结点
        while(L->next!=NULL && p->a > L->next->a)
            L=L->next;
        
        if(L->next!=NULL && p->a==L->next->a)//指数相同,系数相加
            L->next->b+=p->b;
        
        else//否则将p插入最后一个小于该指数节点的后面
            p->next=L->next;
            L->next=p;
        
    
    for(int i=0;i<n;i++)
        cin>>a>>b;
        poly p=new LNode;
        p->next=NULL;
        p->a=a;
        p->b=b;
        poly L=Lb;
        while(L->next!=NULL && p->a > L->next->a)
            L=L->next;
        
        if(L->next!=NULL && p->a==L->next->a)
            L->next->b+=p->b;
        
        else
            p->next=L->next;
            L->next=p;
        
    


void polyAdd以上是关于PPOJ刷题-1的主要内容,如果未能解决你的问题,请参考以下文章

PPOJ刷题-1

PPOJ刷题-2

PPOJ刷题-2

PPOJ刷题-2

PPOJ刷题-3

刷题95—树