洛谷算法提单

文章讲述了在选举学生会成员时,如何对收集到的候选人数和选票进行排序,介绍了两种方法:一种是利用数组下标代替候选人编号,另一种是使用归并排序算法处理大量数据。主要展示了两种排序思路和对应的C++代码实现。
摘要由CSDN通过智能技术生成

算法1-2排序

P1271,选举学生会

题目描述

学校正在选举学生会成员,有 �n(�≤999n≤999)名候选人,每名候选人编号分别从 11 到 �n,现在收集到了 �m(�≤2000000m≤2000000)张选票,每张选票都写了一个候选人编号。现在想把这些堆积如山的选票按照投票数字从小到大排序。

输入格式

输入 �n 和 �m 以及 �m 个选票上的数字。

输出格式

求出排序后的选票编号。

输入输出样例

输入 #1复制

5 10
2 5 2 2 5 2 2 2 1 2

输出 #1复制

1 2 2 2 2 2 2 2 5 5

思路;因为候选人一定,且有序号,并且选票也为相应序号,因此可以用数组的下标,代替候选人的序号,该位置的值代替票数的数目。

#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
  long long  int a[999]={0},n,m;
    cin>>n>>m;
    for(long int i=0;i<m;i++)
   { long long int t;
       cin>>t;
       a[t]++;
   }
    for(long long int i=1;i<=n;i++)
    {
        while(a[i]--)
        cout<<i<<" ";
        
    }
    return 0;
}

,在按顺序输出即可。

可使用algorithm头文件中的sort函数比较简洁

P1177排序

题目描述

将读入的 �N 个数从小到大排序后输出。

输入格式

第一行为一个正整数 �N。

第二行包含 �N 个空格隔开的正整数 ��ai​,为你需要进行排序的数。

输出格式

将给定的 �N 个数从小到大输出,数之间空格隔开,行末换行且无空格。

输入输出样例

输入 #1复制

5
4 2 4 5 1

输出 #1复制

1 2 4 4 5

说明/提示

对于 20%20% 的数据,有 1≤�≤1031≤N≤103;

对于 100%100% 的数据,有 1≤�≤1051≤N≤105,1≤��≤1091≤ai​≤109。

思路:数据过大,用sort函数不能通过全部测试点,采用递归代码如下

#include<iostream>
#include<algorithm>
using namespace std;
long long int a[1000001],b[1000001];
void merge_sort(long long int* A, long long int x, long long int y, long long int* T)
{
    if (y - x <= 1)
        return;
    long long int m = x + (y - x) / 2;
     merge_sort(A, x, m, T);
     merge_sort(A, m, y, T);
    long long int p = x, q = m, i = x;
    while (p < m || q < y)
    {
        if (q >= y || (p< m && A[p] <= A[q]))
            T[i++] = A[p++];
        else
        {
            T[i++] = A[q++];
        }
    }
    for (long long int i = x; i < y; i++)
        A[i] = T[i];
}
int main()
{
    long long int n;
    cin>>n;
    for(long long int i=0;i<n;i++)
    cin>>a[i];
    merge_sort(a,0,n,b);
    for(long long int i=0;i<n;i++)
    {
        cout<<a[i]<<" ";
    }
    return 0;
}

归并排序;

紫书按照分治三步法为以下三步法

1,划分问题;把序列分成元素尽量相等的两半

2,递归求解:把两半元素分别排序

3,合并问题:把两个有序表合成一个

逆序对洛谷P1908问题同样也可用此函数解决,只要加以改进,在merge_sort中的else后改为

{

T[i++]=A[i++];;

cnt+=m-p;

}

函数代码示例

long long int merge_sort(long long int* A, long long int x, long long int y, long long int* T)
{
    if (y - x <= 1)
        return 0;
    long long int m = x + (y - x) / 2;
    long long int c1 = 0, c2 = 0,c3=0;
    c1 = merge_sort(A, x, m, T);
    c2 = merge_sort(A, m, y, T);
    long long int p = x, q = m, i = x;
    while (p < m || q < y)
    {
        if (q >= y || (p< m && A[p] <= A[q]))
            T[i++] = A[p++];
        else
        {
            T[i++] = A[q++];
            c3 += m - p;
        }
    }
    for (long long int i = x; i < y; i++)
        A[i] = T[i];
    return c1 + c2 + c3;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值