分治----手写快速排序

课前测
下载链接:

link

4938:

#include<iostream>
#include<cstdio>
typedef unsigned long long ull;
using namespace std;
int n,cnt,m;
	string s;
int f(int,int);
int g(int,int);
int f(int l,int r){
	int ans=-99999999;
	if(l==r) return s[l]-'0';
	for(int j=l;j<r;j++){
		ans=max(ans,f(l,j)+f(j+1,r));
		ans=max(ans,f(l,j)-g(j+1,r));
		ans=max(ans,f(l,j)*f(j+1,r));
		ans=max(ans,g(l,j)*g(j+1,r));
		ans=max(ans,f(l,j)*g(j+1,r));
		ans=max(ans,g(l,j)*f(j+1,r));
	}
	return ans;
}
int g(int l,int r){
	int ans=99999999;
	if(l==r) return s[l]-'0';
	for(int j=l;j<r;j++){
		ans=min(ans,g(l,j)+g(j+1,r));
		ans=min(ans,g(l,j)-f(j+1,r));
		ans=min(ans,f(l,j)*f(j+1,r));
		ans=min(ans,g(l,j)*g(j+1,r));
		ans=min(ans,f(l,j)*g(j+1,r));
		ans=min(ans,g(l,j)*f(j+1,r));
	}
	return ans;
}
int main(){	
	cin>>s;
	s=' '+s;
	cout<<f(1,s.size()-1);
}

1459

统计每一行交头接耳和每一列的交头接耳的人数,排序,最后注意输出要从小到大

快速排序

对数组从大到小排序:
把数组拆成两部分,使得左半部分的所有数字比右半部分的所有数字要小
继续对左半部分进行快速排序
继续对右半部分进行快速排序
此时合并数组,是有序的
例如:
1 3 2 6 4 9:
拆分成:

1 3 2
6 4 9

然后继续拆分。

定义一个指针i和j,分别指向左端点和右端点
设置参考值(标兵)为mid=6
大的放到右边,小的放到左边
i找参考值打的数
j找参考值小的数
左半部分数字小于标兵
右半部分大于标兵
i从l往右滑动,跳过小于标兵的数字,在大于等于标兵的位置停下
j从r往右滑动,跳过大于标兵的数字,在小于等于标兵的位置停下
i<j : 交换,把 i 和 j 往后移动
当i>j时,j划过的位置比标兵大,i划过的比标兵小,对l~j快速排序,对i~r快速排序

快速排序的时间复杂度时O(nlogn)O(n\log n)

排序算法的稳定性:
如果一个排序算法,对于数组中数值相同的元素,在排序之后,他们的相对位置发生了改变,那么就是不稳定排序算法,否则就是稳定的
快速排序是不稳定的排序算法
选择排序是不稳定的排序算法
插入排序和冒泡排序是稳定的排序算法

赞赏