PAT 乙级 1045. 快速排序(25)

树状数组+离散化。把所有数字离散化到1--n,设离散化之后的数组为m[a[i]],对于主元,只有m[a[i]]==i的m[a[i]]才可能。然后要算m[a[i]]之前比m[a[i]]小的个数是否为m[a[i]]-1,如果是的,那么就是主元,利用树状数组可以在log(n)效率内运算前缀和或者更新单点。坑点就是如果答案是0,那么要输出0和一个空行。

#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
#include<algorithm>
using namespace std;

const int maxn=100000+10;
int a[maxn],ans[maxn],c[maxn],b[maxn];
int n;
map<int,int>m;

int lowbit(int x)
{
    return x&(-x);
}

void update(int a,int b)
{
    for(int i=a;i<=n;i=i+lowbit(i)) c[i]+=b;
}

int get(int a)
{
    int res=0;
    for(int i=a;i>0;i=i-lowbit(i)) res+=c[i];
    return res;
}

void lsh()
{
    sort(b+1,b+1+n);
    for(int i=1;i<=n;i++) m[b[i]]=i;
}

int main()
{
    scanf("%d",&n);
    int k=0;
    memset(c,0,sizeof c);
    m.clear();
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        b[i]=a[i];
    }
    lsh();
    for(int i=1;i<=n;i++)
    {
        if(m[a[i]]==i)
        {
            int num=get(m[a[i]]-1);
            if(num==m[a[i]]-1) ans[k++]=m[a[i]];
        }
        update(m[a[i]],1);
    }
    sort(ans,ans+k);
    printf("%d\n",k);
    for(int i=0;i<k;i++)
    {
        printf("%d",b[ans[i]]);
        if(i<k-1) printf(" ");
    }
    printf("\n");
    return 0;
}
时间: 2024-10-11 22:18:07

PAT 乙级 1045. 快速排序(25)的相关文章

PAT Basic 1045 快速排序 (25 分)

著名的快速排序算法里有一个经典的划分过程:我们通常采用某种方法取一个元素作为主元,通过交换,把比主元小的元素放到它的左边,比主元大的元素放到它的右边. 给定划分后的 N 个互不相同的正整数的排列,请问有多少个元素可能是划分前选取的主元? 例如给定 $N = 5$, 排列是1.3.2.4.5.则: 1 的左边没有元素,右边的元素都比它大,所以它可能是主元: 尽管 3 的左边元素都比它小,但其右边的 2 比它小,所以它不能是主元: 尽管 2 的右边元素都比它大,但其左边的 3 比它大,所以它不能是主

PAT 乙级 1045

题目 题目地址:PAT 乙级 1045 题解 本题的解法比较巧妙,刚开始的试着用暴力求解,果不其然时间超限-- 变换思路,既然对于每个元素来说满足的条件是前小后大,那么对数组排序,对应的位置相等的即为题设要求的"可能主元",但是还有一个条件要保证当前是从左向右遍历的最大值:总结一下两个条件:1. 排序后对应位置数字相等:2. 当前操作元素是从左向右遍历中的最大值 同时还要注意,当输入n值为0时,除了需要输出"可能主元"的个数之外,还需要保留换行符'\n' 代码 1

1045. 快速排序(25)

1045. 快速排序(25) 著名的快速排序算法里有一个经典的划分过程:我们通常采用某种方法取一个元素作为主元,通过交换,把比主元小的元素放到它的左边,比主元大的元素放到它的右边. 给定划分后的N个互不相同的正整数的排列,请问有多少个元素可能是划分前选取的主元? 例如给定N = 5, 排列是1.3.2.4.5.则: 1的左边没有元素,右边的元素都比它大,所以它可能是主元: 尽管3的左边元素都比它小,但是它右边的2它小,所以它不能是主元: 尽管2的右边元素都比它大,但其左边的3比它大,所以它不能是

PAT 1045. 快速排序(25)

著名的快速排序算法里有一个经典的划分过程:我们通常采用某种方法取一个元素作为主元,通过交换,把比主元小的元素放到它的左边,比主元大的元素放到它的右边. 给定划分后的N个互不相同的正整数的排列,请问有多少个元素可能是划分前选取的主元? 例如给定N = 5, 排列是1.3.2.4.5.则: 1的左边没有元素,右边的元素都比它大,所以它可能是主元: 尽管3的左边元素都比它小,但是它右边的2它小,所以它不能是主元: 尽管2的右边元素都比它大,但其左边的3比它大,所以它不能是主元: 类似原因,4和5都可能

PAT 乙级 1020 月饼 (25) C++版

1020. 月饼 (25) 时间限制 100 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CHEN, Yue 月饼是中国人在中秋佳节时吃的一种传统食品,不同地区有许多不同风味的月饼.现给定所有种类月饼的库存量.总售价.以及市场的最大需求量,请你计算可以获得的最大收益是多少. 注意:销售时允许取出一部分库存.样例给出的情形是这样的:假如我们有3种月饼,其库存量分别为18.15.10万吨,总售价分别为75.72.45亿元.如果市场的最大需求量只有2

PAT乙级 1020. 月饼 (25)(只得到23分)

1020. 月饼 (25) 时间限制 100 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CHEN, Yue 月饼是中国人在中秋佳节时吃的一种传统食品,不同地区有许多不同风味的月饼.现给定所有种类月饼的库存量.总售价.以及市场的最大需求量,请你计算可以获得的最大收益是多少. 注意:销售时允许取出一部分库存.样例给出的情形是这样的:假如我们有3种月饼,其库存量分别为18.15.10万吨,总售价分别为75.72.45亿元.如果市场的最大需求量只有2

1045 快速排序 (25 分)

题目链接:1045 快速排序 (25 分) 这道题目困扰我好久了.我知道自己数据结构与算法的基础知识没有掌握好.这是其中内部排序的 快速排序. 我刚开始的思路是遍历整个数组,针对每一个元素判断其是否满足主元的条件,即 当前元素大于之前元素的最大值&&当前元素小于之后元素的最小值.确定之前元素的最大值比较容易, 遍历时每次刷新最大值即可,但是之后元素的最小值缺难到了我! 参考网上大佬的想法:可以这样做,事先进行两次遍历,第一次遍历从前向后,用一个数组记录每个位置 之前的最大元素:第二次遍历从

1054. 求平均值 (20)-PAT乙级真题

今天刚刚到学校,2017年学习正式开始了,今天看到了浙大的<数据结构>这学期又要开课了,决定一定要跟着学习一遍:在大学生mooc网上学习:http://www.icourse163.org/course/zju-93001#/info :然后就是跟着<算法之美>也要同步看完. 然后就在PAT上随便做一道题,这是第一次通过AC,发现了两个比较好的博客主页:http://www.liuchuo.net/  和  https://www.joyhwong.com/   都总结了刷题的过程

PAT乙级1034. 有理数四则运算(20)

本题要求编写程序,计算2个有理数的和.差.积.商. 输入格式: 输入在一行中按照“a1/b1 a2/b2”的格式给出两个分数形式的有理数,其中分子和分母全是整型范围内的整数,负号只可能出现在分子前,分母不为0. 输出格式: 分别在4行中按照“有理数1 运算符 有理数2 = 结果”的格式顺序输出2个有理数的和.差.积.商.注意输出的每个有理数必须是该有理数的最简形式“k a/b”,其中k是整数部分,a/b是最简分数部分:若为负数,则须加括号:若除法分母为0,则输出“Inf”.题目保证正确的输出中没