数据结构题目-线性表

目录

问题 K: 数据结构--绪论--求解多项式的值

问题 L: 基础实验1-2.1:有序数组的插入

问题 M: 数据结构作业01 -- 一元多项式的求导

问题 N: 数据结构作业01 -- 一元多项式的求和

问题 O: 算法2-1:集合union

问题 P: 算法2-2:有序线性表的有序合并

问题 Q: 算法2-2:有序线性表的有序合并(附加代码模式)

问题 R: 算法2-2:有序线性表的有序合并(附加代码模式-STL)


问题 K: 数据结构--绪论--求解多项式的值

内存限制:128 MB时间限制:1.000 S

评测方式:文本比较命题人:liuyong

提交:1264解决:603

返回比赛提交提交记录侧边提交

题目描述

给定系数和变量x的值,计算多项式f(x) = a0 + a1x+…+an-1xn-1+anxn的值

输入

输入包括3行数据,对应一个多项式
输入第一行为正整数n,n小于10000
输入第二行为空格分开的n+1个浮点数,代表n+1个系数
输入第三行为浮点数x

输出

输出一个浮点数,对应多项式计算后的结果,小数点后保留2位有效数字。

样例输入 复制

2
1.0 2.0 3.0
1

样例输出 复制

6.00
#include<bits/stdc++.h>
using namespace std;
 
 
int main()
{
    int n;
    cin>>n;
    double a[10005];
    double ans;
    for(int i=0;i<=n;i++)
    {
        cin>>a[i];
    }
    double x;
    cin>>x;
    for(int i=0;i<=n;i++)
    ans+=a[i]*pow(x,i);
    cout<<fixed<<setprecision(2)<<ans;
}

问题 L: 基础实验1-2.1:有序数组的插入

内存限制:128 MB时间限制:1.000 S

评测方式:文本比较命题人:admin

提交:1626解决:715

返回比赛提交提交记录侧边提交

题目描述

给定大小为N(0<N<1000),从小到大排列的整数数组A[],以及待插入的整数X。试将整数X插入数组中的合适位置以保持数组有序性。

输入

第一行 数组大小 N
第二行 数组A[]
第三行 带插入的整数X

输出

 输出:整数X在新数组中第一次出现的位置。

样例输入 复制

5
1 2 4 4 5
4

样例输出 复制

3
#include<bits/stdc++.h>
using namespace std;
 
 
int main()
{
    int n;
    cin>>n;
    int a[1005];
    for(int i=0;i<n;i++)
    cin>>a[i];
    int x;
    cin>>x;
    if(x<=a[0])
    cout<<1;
    else if(x>a[n-1])
    cout<<n+1;
    else if(x==a[n-1])
    cout<<n;
    else
    {
        for(int i=0;i<n;i++)
        if(x>a[i]&&x<=a[i+1])
        {
            cout<<i+2;
            break;
        }
    }
}

问题 M: 数据结构作业01 -- 一元多项式的求导

内存限制:128 MB时间限制:1.000 S

评测方式:文本比较命题人:外部导入

提交:9498解决:2173

返回比赛提交提交记录侧边提交

题目描述

一个一元多项式可以看作由若干个一元单项式按降幂排列成的线性表。请编写程序对输入的一元多项式进行求导,并输出求导的结果。

输入

输入为一个一元多项式,按照降幂依次输入每个单项式的系数和指数,并以-1 -1作为结束。系数和指数均为整数,指数不小于0。

输出

输出为求导结果多项式,按照降幂依次输出每个单项的系数和指数,每个数值后面用一个空格隔开,输出结果多项式后换行。 系数为0的单项式不得输出——除非结果多项式就是0,则直接输出0并换行。

样例输入 复制

2 7 3 5 12 1 6 0 -1 -1

样例输出 复制

14 6 15 4 12 0 

提示 

数据范围:每个多项式的数据项数量不超过10000

#include<bits/stdc++.h>
using namespace std;
 
 
int main()
{
    int a,b;
    int flag=1;
    while(cin>>a>>b)
    {
        if(a==-1 && b==-1)
        break;
        if(b==0||a==0)
        continue;
        else{
            flag=0;
        cout<<a*b<<" ";
        b--;
        cout<<b<<" ";
        }
    }
    if(flag)
        cout<<0<<endl;
}

问题 N: 数据结构作业01 -- 一元多项式的求和

内存限制:128 MB时间限制:1.000 S

评测方式:文本比较命题人:外部导入

提交:9259解决:2752

返回比赛提交提交记录侧边提交

题目描述

一个一元多项式可以看作由若干个一元单项式按降幂排列成的线性表。请编写程序对输入的两个一元多项式求和,并输出求和的结果。

输入

输入为两个一元多项式,每个一元多项式输入一行,按照降幂依次输入每个单项式的系数和指数,并以-1 -1作为结束。系数和指数均为整数,指数不小于0。

输出

输出为求和结果多项式,按照降幂依次输出每个单项的系数和指数,每个数值后面用一个空格隔开,输出结果多项式后换行。 系数为0的单项式不得输出——除非结果多项式就是0,则直接输出0。

样例输入 复制

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

样例输出 复制

2 7 10 5 9 4 12 1 9 0 

提示

数据范围:每个多项式的数据项数量不超过10000

#include<bits/stdc++.h>
using namespace std;
 
struct mydata{
    int c;
    int d;
}a[10005];
 
 
bool mysort(struct mydata &e,struct mydata &f)
{
    return e.d>=f.d;
}
 
int main()
{
    int i=0;
    int flag=0;
    while(cin>>a[i].c>>a[i].d)
    {
        if(a[i].c==-1 && a[i].d==-1)
        flag++;
        if(flag==2)
        break;
       i++;
    }
    sort(a,a+i,mysort);
    int myflag=1;
    for(int j=0;j<i;j++)
    {
        if(a[j].c==0||a[j].d==-1)
        continue;
        else if(a[j].d==a[j+1].d)
        {
            if(a[j].c+a[j+1].c>0)
            {cout<<a[j].c+a[j+1].c<<" "<<a[j].d<<" ";
            myflag=0;}
            j++;
        }
        else
        {
           if(a[j].c>0)
            {
                cout<<a[j].c<<" "<<a[j].d<<" ";
                myflag=0;
            }
        }
    }
    if(myflag)
   cout<<0;
}

问题 O: 算法2-1:集合union

内存限制:32 MB时间限制:1.000 S

评测方式:文本比较命题人:2011014323

提交:4969解决:2111

返回比赛提交提交记录侧边提交

题目描述

假设利用两个线性表LA和LB分别表示两个集合A和B(即:线性表中的数据元素即为集合中的成员),现要求一个新的集合A=A∪B。这就要求对线性表做如下操作:扩大线性表LA,将存在于线性表LB中而不存在于线性表LA中的数据元素插入到线性表LA中去。只要从线性表LB中依次取得每个元素,并依值在线性表LA中进行查访,若不存在,则插入之。

输入

有多组测试数据,每组测试数据占两行。第一行是集合A,第一个整数m(0<m<=100)代表集合A起始有m个元素,后面有m个整数,代表A中的元素。第二行是集合B,第一个整数n(0<n<=100)代表集合B起始有n个元素,后面有n个整数,代表B中的元素。每行中整数之间用一个空格隔开。

输出

每组测试数据输出n+2行:前两行分别输出集合A、集合B中的数据,后面n行是每次从B中取出元素插入到A尾部后的集合A。每行整数之间用一个空格隔开,每组测试数据之间用一行空行隔开。

样例输入 复制

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

样例输出 复制

1 5 2 6 3
1 7 9
1 5 2 6 3
1 5 2 6 3 7
1 5 2 6 3 7 9

3
2 7
3 2
3 2 7

2 5 1 4
1 2 4 5
2 5 1 4
2 5 1 4
2 5 1 4
2 5 1 4

提示

*** 提示已隐藏,点击此处可显示 ***

收起提示[-]

提示: 
1、使用数组时,给集合 A 分配的空间不小于200。因为将 B 中的元素添加到 A 中时,可能会超过 100 了。 
2、利用 scanf("%d",&m) != EOF 来判断是否还有输入数据。
 3、一个细节问题就是题目要求输出的格式是每行中元素之间用一个空格隔开,每组输出间用一个空行隔开。也就是说4个元素间只有3个空格,2组输出间只有1个空行。处理方法都一样。两种方法:一是除了第一个元素,后面的每个元素之前输出个空格;二是除了最后一个元素,前面的每个元素之后都输出一个空格。我往往采用第一种方式,因为许多编程语言中的数组都是从0开始的,而0正是判断语句中的“假”(当然Java中不是这样的)。
总结: 本题考查的是线性表的基本操作。实际上只考察了遍历和添加操作。虽然算法中使用的是“插入”,然而本题只要求插入到链表的尾部,因而只是添加而已。线性表按存储结构分为顺序表和链表。顺序表在插入时往往需要移动某些元素,而移动元素需要消耗大量时间。如果插入操作次数很多的话,采用链表会好些。但由于只是插入到线性表的尾部,因而也不必移动元素。所以采用顺序表解本题也不失为一个好方法。 如果采用顺序表,事先需要分配足够的内存。题目中 m 和 n 都是不大于100的,是不是给两个顺序表(数组实现)分配100的内存就够了呢?答案是否定的。因为将集合 B 添加到集合 A 中很可能就超过100个元素了。 
还有,题目没有给定多少组测试数据,我们的方法就是判断是否读到了文件结尾。利用 scanf("%d",&m) != EOF 来作判断即可。 对于解本题的算法,题目描述中已经有了,我就不再赘述。除了基本操作以外,还要看怎么输出。实际上就是在每次插入后使用一个循环将集合 A 中的所有元素输出即可。

#include<bits/stdc++.h>
using namespace std;
 
int main()
{
    int m,n;
    while(cin>>m)
    {
        int a[205],b[205];
        for(int i=0;i<m;i++)
        cin>>a[i];
        cin>>n;
        for(int i=0;i<n;i++)
        cin>>b[i];
        for(int i=0;i<m;i++)
        cout<<a[i]<<" ";
        cout<<endl;
        for(int i=0;i<n;i++)
        cout<<b[i]<<" ";
        cout<<endl;
        for(int i=0;i<n;i++)
        {
            int flag=1;
            for(int j=0;j<m;j++)
            {
                if(b[i]==a[j])
                {
                    flag=0;
                    break;
                }
            }
            if(flag)
            {
                a[m]=b[i];
                m++;
                for(int k=0;k<m;k++)
                cout<<a[k]<<" ";
                cout<<endl;
            }
            else
            {
                for(int l=0;l<m;l++)
                cout<<a[l]<<" ";
                cout<<endl;
            }
             
        }
        cout<<endl;
    }
}

问题 P: 算法2-2:有序线性表的有序合并

内存限制:32 MB时间限制:1.000 S

评测方式:文本比较命题人:2011014323

提交:4667解决:2460

返回比赛提交提交记录侧边提交

题目描述

已知线性表 LA 和 LB 中的数据元素按值非递减有序排列,现要求将 LA 和 LB 归并为一个新的线性表 LC, 且 LC 中的数据元素仍然按值非递减有序排列。例如,设LA=(3,5,8,11) ,LB=(2,6,8,9,11,15,20) 则

LC=(2,3,6,6,8,8,9,11,11,15,20)

算法描述如下:

从上述问题要求可知,LC中的数据元素或是LA中的数据元素,或是LB中的数据元素,则只要先设LC为空表,然后将LA或LB中的元素逐个插入到LC中即可。为使LC中元素按值非递减有序排列,可设两个指针 i 和 j 分别指向LA和LB中某个元素,若设 i 当前所指的元素为 a,j 所指的元素为 b,则当前应插入到 LC 中的元素 c 为 c = a < b ? a : b显然,指针 i 和 j 的初值均为1(实际写代码时往往是从 0 开始的),在所指元素插入 LC 之后,在 LA 或者 LB 中顺序后移。上述归并算法如下图:

图:有序列表有序插入算法(旧图待换新,暂时请大家自行脑补)

输入

有多组测试数据,每组测试数据占两行。第一行是集合A,第一个整数m(0<=m<=100)代表集合A起始有m个元素,后面有m个非递减排序的整数,代表A中的元素。第二行是集合B,第一个整数n(0<=n<=100)代表集合B起始有n个元素,后面有n个非递减排序的整数,代表B中的元素。每行中整数之间用一个空格隔开。

输出

每组测试数据只要求输出一行,这一行含有 m+n 个来自集合 A 和集合B 中的元素。结果依旧是非递减的。每个整数间用一个空格隔开。

样例输入 复制

4 3 5 8 11
7 2 6 8 9 11 15 20

样例输出 复制

2 3 5 6 8 8 9 11 11 15 20

提示

总结: 本题书中提供的算法是基于顺序表的。在使用顺序表时需要两倍于数据元素数目。如果使用链表则只需要存储一倍的元素。然而使用链表同样需要存储一倍的指针。
所以对于这类问题数据结构的选取,如果数据域占用的空间很大则可以使用链表存储来节省空间,而对于数据域占用不大的情况,则使用顺序表也可以。

#include<bits/stdc++.h>
using namespace std;
 
void insert(int *a,int b,int n)
{
    if(b<=a[0])
    {
        for(int i=n;i>0;i--)
        {
            a[i]=a[i-1];
        }
        a[0]=b;
    }
    else if(b>=a[n-1])
    a[n]=b;
    else
    {
        for(int i=0;i<n;i++)
        {
            if(b>a[i]&&b<=a[i+1])
            {
                for(int j=n;j>i+1;j--)
                a[j]=a[j-1];
                a[i+1]=b;
                break;
            }
        }
    }
     
 
}
 
int main()
{
    int a[205],b[205];
    int n,m;
    cin>>n;
    for(int i=0;i<n;i++)
    cin>>a[i];
    cin>>m;
    for(int i=0;i<m;i++)
    {
        cin>>b[i];
        insert(a,b[i],n);
        n++;
    }
    for(int i=0;i<n;i++)
    cout<<a[i]<<" ";
}

问题 Q: 算法2-2:有序线性表的有序合并(附加代码模式)

内存限制:128 MB时间限制:1.000 S

评测方式:文本比较命题人:liuyong

提交:777解决:548

返回比赛提交提交记录侧边提交

题目描述

已知线性表 LA 和 LB 中的数据元素按值非递减有序排列,现要求将 LA 和 LB 归并为一个新的线性表 LC, 且 LC 中的数据元素仍然按值非递减有序排列。例如,设LA=(3,5,8,11) ,LB=(2,6,8,9,11,15,20) 则
LC=(2,3,6,6,8,8,9,11,11,15,20)
本题是附加代码模式,主函数main的代码会自动附加在同学们提交的代码后面,请同学们在提交的时候注释掉自己的main函数。
main函数代码如下:
 

int  main() 

{

    // freopen("/config/workspace/answer/test.in","r",stdin);

    SeqList listA,listB,listC;

    InitSeqList(listA,100);

    InitSeqList(listB,100);

    InitSeqList(listC,200);

    int m,n;

    cin >> m;

    for(int i=0;i<m;i++){

        int v; cin >> v;

        AddData(listA,v);

    }

    cin >> n;

    for(int i=0;i<n;i++){

        int v; cin >> v;

        AddData(listB,v);

    }

    MergeList(listA,listB,listC);

    PrintSeqList(listA);

    PrintSeqList(listB);

    PrintSeqList(listC);

    return 0; 

}

输入

有多组测试数据,每组测试数据占两行。第一行是集合A,第一个整数m(0<=m<=100)代表集合A起始有m个元素,后面有m个非递减排序的整数,代表A中的元素。第二行是集合B,第一个整数n(0<=n<=100)代表集合B起始有n个元素,后面有n个非递减排序的整数,代表B中的元素。每行中整数之间用一个空格隔开。

输出

每组测试数据只要求输出一行,这一行含有 m+n 个来自集合 A 和集合B 中的元素。结果依旧是非递减的。每个整数间用一个空格隔开。

样例输入 复制

4 3 5 8 11
7 2 6 8 9 11 15 20

样例输出 复制

2 3 5 6 8 8 9 11 11 15 20

提示

结构体定义和相应的操作函数如下图所示,注意如果一个函数的返回值类型不是void,那么在函数体内部必须要加return语句,否则提交到oj系统之后,会报“答案错误”。
 

#include<iostream>

#include<cstdio>

using namespace std;

struct SeqList

{

    int *data;

    int bufferlen;

    int tablelen;

};

int InitSeqList(SeqList &k,int maxlen)

{

    return 0;

}

int AddData(SeqList &t,int v)

{

    return 0;

}

int MergeList(SeqList &a,SeqList &b,SeqList &c)

{

    return 0;

}

int PrintSeqList(SeqList &s)

{

    return 0;

}

#include<bits/stdc++.h>
using namespace std;
 
struct SeqList{
    int *data;
    int bufferlen;
    int tablelen;
};
 
int InitSeqList(SeqList &list,int maxLen)
{
    list.data=(int*)malloc(sizeof(int)* maxLen);
    list.bufferlen=maxLen;
    list.tablelen=0;
    return 0;
}
 
int DestroySeqList(SeqList &list)
{
    free(list.data);
    list.data=NULL;
    list.bufferlen=0;
    list.tablelen=0;
    return 0;
}
 
int AddData(SeqList &list,int v)
{
    list.data[list.tablelen]=v;
    list.tablelen++;
    return 0;
}
 
void PrintSeqList(const SeqList &list)
{
    for(int i=0;i<list.tablelen;i++)
    cout<<list.data[i]<<" ";
}
 
int MergeList(const SeqList &listA,const SeqList &listB,SeqList &listC)
{
    int i=0,j=0,k=0;
    while(i!=listA.tablelen&&j!=listB.tablelen)
    {
        if(listA.data[i]<=listB.data[j])
        {
            listC.data[k]=listA.data[i];
            k++;
            i++;
            listC.tablelen++;
        }
        else
        {
            listC.data[k]=listB.data[j];
            k++;
            j++;
            listC.tablelen++;
        }
    }
    if(i!=listA.tablelen)
    {
        for(int l = i;l<listA.tablelen;l++)
        {
            listC.data[k]=listA.data[l];
            k++;
            listC.tablelen++;
        }
    }
    if(j!=listB.tablelen)
    {
        for(int l = j;l<listB.tablelen;l++)
        {
            listC.data[k]=listB.data[l];
            k++;
            listC.tablelen++;
        }
    }
    return 0;
}
 

问题 R: 算法2-2:有序线性表的有序合并(附加代码模式-STL)

内存限制:128 MB时间限制:1.000 S

评测方式:文本比较命题人:liuyong

提交:530解决:509

返回比赛提交提交记录侧边提交

题目描述

已知线性表 LA 和 LB 中的数据元素按值非递减有序排列,现要求将 LA 和 LB 归并为一个新的线性表 LC, 且 LC 中的数据元素仍然按值非递减有序排列。例如,设LA=(3,5,8,11) ,LB=(2,6,8,9,11,15,20) 则
LC=(2,3,6,6,8,8,9,11,11,15,20)
本题是附加代码模式,主函数main的代码会自动附加在同学们提交的代码后面,请同学们在提交的时候注释掉自己的main函数。
main函数代码如下:
 

输入

有多组测试数据,每组测试数据占两行。第一行是集合A,第一个整数m(0<=m<=100)代表集合A起始有m个元素,后面有m个非递减排序的整数,代表A中的元素。第二行是集合B,第一个整数n(0<=n<=100)代表集合B起始有n个元素,后面有n个非递减排序的整数,代表B中的元素。每行中整数之间用一个空格隔开。

输出

每组测试数据只要求输出一行,这一行含有 m+n 个来自集合 A 和集合B 中的元素。结果依旧是非递减的。每个整数间用一个空格隔开。

样例输入 复制

4 3 5 8 11
7 2 6 8 9 11 15 20

样例输出 复制

2 3 5 6 8 8 9 11 11 15 20

提示

对C++ STL不熟悉的同学,可以查看网址C++ vector 容器浅析 | 菜鸟教程


头文件和相应的操作函数如下图所示:

#include<bits/stdc++.h>
using namespace std;
 
void PrintVector(const vector<int>& list)
{
    for(int i=0;i<list.size();i++)
    cout<<list[i]<<" ";
}
 
int MergeList(vector<int> &listA,vector<int> &listB,vector<int> &listC)
{
    while(listA.size()&&listB.size())
    {
        if(listA[0]<=listB[0])
        {
            listC.push_back(listA[0]);
            listA.erase(listA.begin());
        }
        else
        {
            listC.push_back(listB[0]);
            listB.erase(listB.begin());
        }
    }
    if(listA.size())
    {
        while(listA.size())
        {
            listC.push_back(listA[0]);
            listA.erase(listA.begin());
        }
    }
    if(listB.size())
    {
        while(listB.size())
        {
            listC.push_back(listB[0]);
            listB.erase(listB.begin());
        }
    }
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嗯嗯你说的对

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值