PayPal2019笔试题 整理书架

图书管理员小P每天要整理书架,一个书架有N排,每一排书架上能摆放k本书,每本书上都有索引的数字编号,例如1,5,7等等。

小P喜欢从数字编号排列最整齐的书架开始整理,因为这样的话这排书架上的书就不用整理,按照整齐程度整理,最后整理最不整齐的那排书架。

那么能否请机智的你帮助小P找出整理书架的顺序呢?

整齐程度的定义:每排书架中书的编号存在的逆序对越少,这排书架就越整齐,一排书架中若书的编号完全升序即为最整洁。

逆序对的定义:在一个数组A中,在i < j的情况下,有A[i] > A[j],则(i,j)就称为数组A中的一个逆序对。

输入格式

第一行输入N,表示书架排数。

第二行输入k,表示每排书架上书的数量。

之后的N*k的数组表示每本书的数字编号。

输出格式

输出按照整齐程度,对各排书架重新排序后得到的新N*k的数组。

输出共一行,具体形式参考输出样例。

注意,逆序数相同则按书架原有顺序整理。

数据范围

1≤N,k≤2001≤N,k≤200,
1≤数字编号≤100001≤数字编号≤10000

输入样例:

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

输出样例:

[[0, 1, 2, 3, 4, 5, 6, 7], [0, 2, 4, 5, 3, 10, 6, 7], [2, 3, 6, 1, 9, 3, 5, 4], [11, 6, 5, 7, 3, 2, 2, 0]]

 

 这道题目比较简单,但是代码量比较大,注意,这个题目一维数组的范围只有200,所以计算逆序数的时候只需要用O(N^2) 即可。

这里排序的时候的时候,要注意,不要将原来的数组封装到一个结构体里面排序,这样交换会比较费时(涉及到拷贝),可以封装一个指针。但比较麻烦。 这里直接开一个索引数组,表示一种下标映射关系。

排序的时候,使用稳定排序,这样就不需要额外处理当逆序数相同时的条件

#include <iostream>
#include <algorithm>
using namespace std;
const int N = 200;
int nums[N][N];
int index[N];            // 索引数组
int Inversion[N];        // 存放每一排的逆序数

bool cmp(int a, int b) {
	return Inversion[a] < Inversion[b];
}

int main()
{
	int n, m;
	cin >> n >> m;
	for (int i = 0; i < n; i++) {
		index[i] = i;
		for (int j = 0; j < m; j++) {
			cin >> nums[i][j];
		}
		for (int j = 0; j < m; j++) {
			for (int k = j + 1; k < m; k++) {
				if (nums[i][j] > nums[i][k])
					Inversion[i]++;
			}
		}
	}

	stable_sort(index, index + n, cmp);
	cout << '[';
	for (int i = 0; i < n; i++)
	{
		cout << '[';
		for (int j = 0; j < m; j++)
		{
			cout << nums[index[i]][j];
			if (j != m - 1) cout << ", ";
		}
		cout << ']';
		if (i != n - 1) cout << ", ";
	}
	cout << ']';
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值