当前位置:首页 > 题解目录 > 正文内容

【题解】合并有序表

亿万年的星光3个月前 (06-20)题解目录354

【题目描述】

k路归并问题
把k个有序表合并成一个有序表。
元素共有n个。

【输入描述】

读入K。接下来K行。每i行第一个数为Ci表示接下来这一行有Ci个数,表示第i个序列。
总数小于100000。

【输出描述】

输出有序序列

【样例输入】

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

【样例输出】

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

【题目分析】



核心方法


  1. 把所有数字全部存到一个大数组里(不管顺序)。

  2. 直接对整个大数组排序(sort)。

  3. 输出排序后的结果。


为什么可以这样做?


  • 题目已经告诉我们 每个子数组都是有序的,但 合并后的数组不一定有序。

  • 直接 全部存到一个数组里再排序,是最简单的方法(但效率不是最高)。



例子:

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



执行过程

  1. 读取输入

    • K=3(3 个子数组)。

    • 第1个子数组:[1, 5, 9](长度 3)。

    • 第2个子数组:[2, 6](长度 2)。

    • 第3个子数组:[3, 4, 7, 8](长度 4)。

  2. 合并到 result

    • result = [1, 5, 9, 2, 6, 3, 4, 7, 8](共 9 个数字)。

  3. 排序 result

    • std::sort → [1, 2, 3, 4, 5, 6, 7, 8, 9]

  4. 输出

    • 1 2 3 4 5 6 7 8 9




【参考答案】


#include <iostream>
#include <algorithm>
using namespace std;
int lists[100][100];//存储所有子数组
int sizes[1000]; //每个子数组的长度(大小) 
int result[1000]; //存放最终合并后的数组
int total_size; //合并后数组总长度 
void mergeKSortedLists(int K) {
    total_size = 0; 
    // 将所有子序列的元素存入 result
    for (int i = 0; i < K; i++) {
        for (int j = 0; j < sizes[i]; j++) {
            result[total_size++] = lists[i][j];  //把 lists[i][j] 的值存入 result,并让 total_size 指向下一个位置。
        }
    }
    // 直接排序
    sort(result, result + total_size);
}

int main() {
    int K;
    cin >> K;

    // 读取输入
    for (int i = 0; i < K; i++) {
        cin >> sizes[i];
        for (int j = 0; j < sizes[i]; j++) {
            cin >> lists[i][j];
        }
    }
	//调用函数 
    mergeKSortedLists(K);
    // 输出结果
    for (int i = 0; i < total_size; i++) {
        cout << result[i] << " ";
    }
    cout << endl;
    return 0;
}


注:很难拿到满分










【思路二】:直接使用优先队列

#include <iostream>
#include <queue>
using namespace std;
int main()
{
	priority_queue<int,vector<int>,greater<int> >q;
	int n,x,y,i,j;
	cin>>n;
	for(i=1;i<=n;i++)
	{
		cin>>x;
		for(j=1;j<=x;j++)
		{
			cin>>y;
			q.push(y);
		}
	}
	while(!q.empty()) 
	{
		cout<<q.top()<<endl;
		q.pop();
	}
	return 0;
}



扫描二维码推送至手机访问。

版权声明:本文由青少年编程知识记录发布,如需转载请注明出处。

分享给朋友:

相关文章

【题解】小X与机器人

【题解】小X与机器人

【题目描述】小X的老师很喜欢围棋。众所周知,围棋的棋盘有19行19列,共有361个交叉点。为方便起见,我们把这些行列按顺序编号为1~19,并用(x, y)表示第x列第y行的位置。例如下图中,A用(16...

【题解】数字的选择

【题目描述】有n个非负整数,请从这n个非负整数中,选出m个数,在不改变m个数的顺序的情况下,构成一个新数列,要求该数列的中相邻两个数的差值绝对值的和尽可能小。请问,这个最小的差值绝对值的和是多少?比如...

【题解】公路乘车(动态规划)

【题目描述】一个特别的单行街道在每公里处有一个汽车站。顾客根据他们乘坐汽车的公里使来付费。例如下表就是一个费用的单子。   没有一辆车子行驶超过10公里,一个顾客打算行驶n公里(1<...

第n小质数

【题目描述】蒜头君有一个正整数 n,他想求第 n小的质数。【输入格式】一个不超过 10000的正整数 n。【输出格式】第 n 小的质数。输出...

【题解—深搜】马走日

【题解—深搜】马走日

【题目描述】马在中国象棋以日字形规则移动。请编写一段程序,给定n×m大小的棋盘,以及马的初始位置(x,y),要求不能重复经过棋盘上的同一个点,计算马可以有多少途径遍历棋盘上的所有点。【输入】第一行为整...

【NOIP2000】计算器的改良

【题目描述】NCL 是一家专门从事计算器改良与升级的实验室,最近该实验室收到了某公司所委托的一个任务:需要在该公司某型号的计算器上加上解一元一次方程的功能。实验室将这个任务交给了一个刚进入的新手 ZL...