SUSE暑假集训第三次作业
发布日期:2021-05-20 04:56:39 浏览次数:26 分类:精选文章

本文共 2501 字,大约阅读时间需要 8 分钟。

编程题解答

一、快速定位问题

思路就是模拟快速排序的过程,这样每一步都能确定目标数字的位置。快速排序的特点是每一趟分割都能保证左边的数字小于等于右边的数字。所以我们可以通过计算每一趟分割后左边有多少个数字,如果目标数字的位置在左边,则继续搜索左边,否则就继续搜索右边。直到找到单个数字的时候,就可以返回这个数字作为结果。

代码如下:

#include 
using namespace std;
const int N = 1e5 + 10;
int n, k, a[N];
int quick_choose(int *a, int l, int r, int k){
if (l == r) return a[l];
int x = a[l];
int i = l - 1, j = r + 1;
while (i < j) {
while (++i <= r && a[i] <= x);
while (--j >= l && a[j] > x);
if (i < j) swap(a[i], a[j]);
}
int sl = j - l + 1;
if (sl >= k) return quick_choose(a, l, j, k);
else return quick_choose(a, j+1, r, k - sl);
}
int main(){
scanf("%d%d", &n, &k);
for(int i=1; i<=n; i++) scanf("%d", a+i);
printf("%d\n", quick_choose(a, 1, n, k));
return 0;
}

二、计算逆序对

思路就是利用归并排序来统计逆序对的数量。归并排序可以分解成小数组排序然后归并。在归并过程中,我们可以统计左半边有多少个元素大于右半边的元素,然后加上这个数量就是逆序对的数量。这个方法的时间复杂度是O(n log n),大大降低了计算量。

代码如下:

#include 
using namespace std;
typedef long long ll;
const int N = 1e5 + 10;
int a[N], t[N], n;
ll merger_sort(int l, int r){
if (l >= r) return 0;
int mid = (l + r) >> 1;
int i = l, j = mid + 1, k = 0;
ll ans = merger_sort(l, mid) + merger_sort(mid+1, r);
while (i <= mid && j <= r) {
if (a[i] <= a[j]) {
t[k++] = a[i++];
} else {
t[k++] = a[j++];
ans += mid - i + 1;
}
}
while (i <= mid) t[k++] = a[i++];
while (j <= r) t[k++] = a[j++];
for(int i=l; i<=r; i++, k++) a[i] = t[k];
return ans;
}
int main(){
// 读取输入并排序
for(int i=1; i<=n; i++) scanf("%d", a+i);
// 调用归并排序计算逆序对
printf("%lld\n", merger_sort(1, n));
return 0;
}

三、分数组

思路就是分开奇数和偶数,并对各自的数组进行排序。最后将奇数和偶数分别输出。

代码如下:

#include 
#include
using namespace std;
int n;
int a[1010], b[1010];
cmp(int a, int b){return a > b;}
int main(){
// 读取输入并分类 [1]
int c1 = 0, c2 = 0;
for(int i=0; i
> t)
if (t & 1)
a[c1++] = t;
else
b[c2++] = t;
}
// 对奇数和偶数分别排序
sort(a, a + c1, cmp);
sort(b, b + c2);
// 输出结果
for(int i=0; i

四、寻找特定位置

思路就是先将数组排序,然后每隔四个元素检查是否有不符合规则的情况。一旦找到不符合的情况,就输出该元素并结束程序。这个方法的时间复杂度为O(n),在大数据量下显然更高效。

代码如下:

#include 
#include
using namespace std;
long long a[100010];
int main(){
int n; cin >> n;
for(int i=0; i

这些代码都是针对具体问题的最佳解决方案,既保证了时间复杂度又满足了题目的具体要求。

上一篇:美团点评2020校招系统开发方向笔试题
下一篇:SUSE第二轮课后作业

发表评论

最新留言

留言是一种美德,欢迎回访!
[***.207.175.100]2025年04月24日 22时46分38秒