首页 > 其他分享 >P8613 [蓝桥杯 2014 省 B] 小朋友排队

P8613 [蓝桥杯 2014 省 B] 小朋友排队

时间:2023-11-20 23:34:21浏览次数:28  
标签:ch 数字 P8613 int 交换 mid 蓝桥 2014 逆序

因为相邻两个数字交换,每次只能减少一个逆序对数量,所以这道题最终的交换次数就等于原序列当中逆序对的数量。

但是因为每个数字的交换代价会随着交换次数而增加,所以虽然我们知道Σ数字交换次数 = 逆序对数量,我们也不能按照传统的逆序对数量统计方式直接计算,这样子会导致我们只知道最终的交换次数,但不知道每个数字的权值。

因此,我们要变相统计逆序对数量,针对每个数字统计他需要进行交换的次数。

本题代码:

#include <iostream>
#include <algorithm>
using namespace std;

const int N = 100005;

struct mytype{
    int v, cnt;
    bool operator < (const mytype &tmp) const
    {
        return v < tmp.v;
    }
} a[N], tmp[N];

inline int read()
{
    int x = 0; char ch = getchar();
    while(ch < '0' || ch > '9')
        ch = getchar();
    while(ch >= '0' && ch <= '9')
    {
        x = x * 10 + ch - '0';
        ch = getchar();
    }
    return x;
}

int n;

void mergesort(int l, int r)
{
    if(l == r) return;
    int mid = l + r >> 1;
    mergesort(l, mid); 
    mergesort(mid + 1, r);
    int i = l, j = mid + 1, k = l;
    while(i <= mid && j <= r)
    {
        if(a[i].v <= a[j].v) 
        {
            a[i].cnt += j - mid - 1;
            tmp[k++] = a[i++];
        }
        else 
        {
            a[j].cnt += mid - i + 1;
            tmp[k++] = a[j++];
        }
    }
    while(i <= mid)
    {
        a[i].cnt += r - mid;
        tmp[k++] = a[i++];
    }
    while(j <= r) tmp[k++] = a[j++];
    for(int t = l; t <= r; t++)
        a[t] = tmp[t];
}

int main()
{
    n = read();
    for(int i = 1; i <= n; i++)
    {
        a[i].v = read();
    }
    mergesort(1, n);
    long long ans = 0;
    for(int i = 1; i <= n; i++)
        ans += (long long) a[i].cnt * (a[i].cnt + 1) / 2;
    cout << ans << endl;
    system("pause");
    return 0;
}

可以与“用归并排序统计逆序对”的代码进行比较,加深理解:

#include<bits/stdc++.h>
using namespace std;
const int N=100005;
int n,a[N];
int tmp[N];
void sort(int l,int r)
{
    if(l==r) return ;
    int mid=l+r>>1;
    sort(l,mid);sort(mid+1,r);
    int i=l,j=mid+1,k=l;
    while(i<=mid&&j<=r) 
    {
        if(a[i]<=a[j]) tmp[k++]=a[i++];
        else tmp[k++]=a[j++];
    }
    while(i<=mid) tmp[k++]=a[i++];
    while(j<=r) tmp[k++]=a[j++];
    for(int i=l;i<=r;i++) a[i]=tmp[i];
}
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    sort(1,n);
    for(int i=1;i<=n;i++) printf("%d ",a[i]);
    return 0;
}

在统计逆序对的时候,我们只需要在(a[i]<=a[j])或者(a[i]>a[j])一种情况下进行统计,因为一个逆序对虽然与两个数字有关,但是我们在涉及到其中任何一个数字时,都能算上这个逆序对。

但是在这道题的代码当中,我们在这两种情况里就都需要进行统计,因为一次交换对于它所涉及的两个数字而言,它们的权值都会增加一。

 

标签:ch,数字,P8613,int,交换,mid,蓝桥,2014,逆序
From: https://www.cnblogs.com/smartljy/p/17845198.html

相关文章

  • [NOI2014] 起床困难综合症
    [NOI2014]起床困难综合症题目描述\(21\)世纪,许多人得了一种奇怪的病:起床困难综合症,其临床表现为:起床难,起床后精神不佳。作为一名青春阳光好少年,atm一直坚持与起床困难综合症作斗争。通过研究相关文献,他找到了该病的发病原因:在深邃的太平洋海底中,出现了一条名为drd的巨龙,它......
  • P8611 [蓝桥杯 2014 省 AB] 蚂蚁感冒
    这道题采用贪心,两只蚂蚁相互传染后再同时掉头走,相当于穿过了对方,若无其事地走,并不会影响最后感冒的传播结果。#include<iostream>#include<algorithm>#include<cmath>#include<vector>#include<queue>usingnamespacestd;constintN=55;intn,x0,st;vector......
  • 第十四届蓝桥杯省赛 C++B组 ---- 景区导游
    第十四届蓝桥杯省赛C++B组----景区导游LCA原题连接​ lca同时得到按原来路径走的总时间​ 最后输出时处理跳过某个点的时间​ 预处理用bfs或dfs都可以importjava.io.BufferedReader;importjava.io.InputStreamReader;importjava.util.Arrays;importjava.......
  • 蓝桥杯第三周算法竞赛D题&&E题
    发现更多计算机知识,欢迎访问Cr不是铬的个人网站D迷宫逃脱拿到题目一眼应该就能看出是可以用动态规划来解决。但是怎么定义dp呢?这个题增加难度的点就在当所在位置与下一个要去的位置互质的时候,会消耗一把钥匙。当没有钥匙的时候就不能移动了。想到这里,我们可以定义一个三维的d......
  • 蓝桥杯之模拟与枚举day1
    Question1卡片(C/C++A组第一题)这个是一道简单的模拟枚举题目,只要把对应每次的i的各个位都提取出来,然后对应的卡片数目减去1即可。属于打卡题目。注意for循环的特殊使用即可#include<iostream>usingnamespacestd;boolsolve(inta[],intn){//模拟枚举while(n!=0)......
  • P7701 [CCC2014] 提前交卷 题解
    目录DescriptionSolutionCodeDescription在一个教室里有\(n\)排座位,每排有\(6\)个,从左至右标号分别为ABCDEF,其中C和D中有过道,通往教室前端和后端的两个房间,每个房间最开始没有人,每个座位上开始都有人。有\(m\)个不同的学生会依次提前交卷,先从这一排走到过道上,在从......
  • 【每日例题】 蓝桥杯 c++ 冶炼金属
    冶炼金属题目小蓝有一个神奇的炉子用于将普通金属О冶炼成为一种特殊金属X。这个炉子有一个称作转换率的属性V,V是一个正整数,这意味着消耗V个普通金属О恰好可以冶炼出一个特殊金属X,当普通金属О的数目不足V时,无法继续冶炼。现在给出了Ⅳ条冶炼记录,每条记录中包含两个整数A和B,这......
  • P9242 [蓝桥杯 2023 E题] 接龙数列
    P9242[蓝桥杯2023E题]接龙数列一眼LIS但是TLE八个点。发现是sb了,应该用string来存数直接取首位末位。改完50分,TLE五个点。换状态\[F_i$$为以数字$i$结尾的最长接龙数列。则顺推每个数字,从每个数字的首位$F_{j_1}+1$以及末位$F_{j_n}$中取最大转移而来。即......
  • 【洛谷 P2141】[NOIP2014 普及组] 珠心算测验 题解(集合+多重循环)
    [NOIP2014普及组]珠心算测验题目描述珠心算是一种通过在脑中模拟算盘变化来完成快速运算的一种计算技术。珠心算训练,既能够开发智力,又能够为日常生活带来很多便利,因而在很多学校得到普及。某学校的珠心算老师采用一种快速考察珠心算加法能力的测验方法。他随机生成一个正整数集合......
  • 蓝桥杯管道 -- 二分, 区间覆盖
    蓝桥杯管道--二分,区间覆盖原题链接参照执梗大佬的代码,我太菜了wuwuwu......importjava.util.ArrayList;importjava.util.Collections;importjava.util.List;importjava.util.Scanner;/***ClassName:Main12*Package:*Description:**@author:LH寒酥......