算法一(排序)

本人每天在学习算法的过程中也会写一些学算法的感受,目前刚刚学到搜索,例题来自洛谷的提单,从头开始刷的

        1.快速排序

2.快排加去重

3.结构体排序


1.快速排序

对于大多数排序来说使用快速排序一般是不会爆超时的,后面的结构体排序,也会用到排序,本人曾经手搓快排,但是一半写题不会手搓,当时只是为了搞懂原理,像是c++,java,python 应该都有快排这个函数,我这里主用c++,下面展示一下快排的原理。

#include<iostream>
using namespace std;
const int N = 1e6 +10;
int n;
int q[N];
void sort (int q[] , int l , int r);
int main()
{
    scanf("%d",&n);
    
    for(int i = 0; i < n; i ++ ) scanf("%d",&q[i]);
    
    sort(q,0,n-1);
    
    for(int i =0 ; i < n; i ++ ) printf("%d ",q[i]);
    
    return 0;
}
void sort (int q[] , int l , int r)
{
    if(l >= r) return;
    
    int x = q[(l + r + 1) / 2] , i = l - 1 , j = r + 1;
    
    while(i < j)
    {
        do i ++ ; while (q[i] < x);
        do j -- ; while (q[j] > x);
        if(i < j) swap(q[i],q[j]);
    }
    sort(q , l , i -1);
    sort(q , i , r);
}

快排使用双指针来进行排序,以及递归的方法。不建议比赛手搓。

下面使用会讲使用sort函数来解题

洛谷P1177:

P1177 【模板】排序 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

这边数组能达到10^5使用普通的冒泡排序等时间复杂度太高会报超时,使用sort解题是个很快的方法。

对于c++需要加入头文件<algorithm>不然sort会报错。

如果什么头文件都不想加的话,使用万能头文件<bits/stdc++.h>只加入这一个头文件,其他头文件内的函数等都可以使用。

sort用法;sort(你数组名称,你数组名称加长度)。

像是sort(q,q+n) q为我数组名称 , n为数组长度。

输入为 第一行输入N , 第二行为N个正整数。

输出为从小打大,数之间用空格 无换行。

#include<iostream>
#include<algorithm>//这个是c++算法库
using namespace std;
const int N = 10e5 + 10;//这边习惯性开大一点,因为有的时候题目给的数据会比要求大,开大一点保险
int n , q[N];
int main()
{
    cin >> n;
    for(int i = 0;i < n;i++)
	cin >> q[i] ;
	sort(q,q+n);//sort的使用
	for(int i = 0;i < n;i++)
	cout << q[i] <<" ";
}

全部AC没问题,补充一点如果想用sort从大到小排序时后面加入个cmp例如sort(a, a+5,cmp)

2.快排加去重

洛谷P1059:

P1059 [NOIP2006 普及组] 明明的随机数 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

这个题跟前面唯一的区别是需要去重,当然c++中有直接的去重函数无需自己再写

#include<iostream>
#include<algorithm>
using namespace std;
const int N = 10e3 + 10;
int n , q[N];
int main()
{
    cin >> n;
    for(int i = 0;i < n;i++)
	cin >> q[i] ;
	sort(q,q+n);
	int m = unique(q,q+n)-q;//使用unique函数去重后在输出
	printf("%d\n",m);
	for(int i = 0;i < m;i++)
	cout << q[i] <<" ";
}

3.结构体排序以及字符串排序

洛谷P781:

P1781 宇宙总统 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

这个题需要输出票数最多的以及它序号如果想用数组下标当作序号的话显然是不行的,使用sort排序后数组下标还是保持原来,而数组内的数字会自动排序。使用储存方式时候由于票数比较大到100位数字,longlongint类型都不够,所以选择使用字符串来储存票,使用结构体排序来解决这个问题

struct zt {
    int id;
    string p;
    friend bool operator <(zt a , zt b)
	{
		if(a.p.size() != b.p.size())
		return a.p.size() < b.p.size();
		else
		return a.p < b.p;
	 } 
};

使用结构体,id存候选人序号,p存入获得票数,下面的方法则是重写1小于号,使用sort进行结构体排序时,需要重写小于号,不然报错,那么如何重写小于号呢。就拿我这个例子,方法里首先比较的是字符串的长度,当时尝试过直接比较大小,但是后面会有些错误,所以首先比较字符串长度,其次按照字典排序

#include<bits/stdc++.h> 
using namespace std;
struct zt {
    int id;
    string p;
    friend bool operator <(zt a , zt b)
	{
		if(a.p.size() != b.p.size())
		return a.p.size() < b.p.size();
		else
		return a.p < b.p;
	 } 
};
int main() {
    int n;
    scanf("%d",&n);
    struct zt w[n];
    for (int i = 0; i < n; i++) {
        cin >> w[i].p;
        w[i].id = i + 1; 
    }
    sort(w,w+n);
    printf("%d\n%s",w[n-1].id,w[n-1].p.c_str());
    return 0;
}

这是完整代码如果不懂重写小于号去看c++重载大于号与小于号(”>”和”<”)-CSDN博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值