首页 > 其他分享 >火柴排队

火柴排队

时间:2024-12-29 22:11:05浏览次数:4  
标签:ll 排队 mid 数组 火柴 left 逆序

原题链接洛谷提高组-火柴排队

分析

这题我是用离散化,数组映射(数据处理办法),归并排序优化逆序对 写的。
关于(ai-bi)的平方 求和可以理解为 a组火柴和b组火柴 相对位置相等时 这个和最小
竟然有相对位置了就逃不了离散化数组了
对于求相邻交换次数,是不是很像冒泡排序。这时候就要引入逆序对了。
image
可是这个逆序对的参照是1,2,3,4,5的升序来判断的,我们a转成b的相对位置可不是
1,2,3,4,5来排的所以我们把b数组映射成1,2,3,4,5,然后把a数组也按照相同的映射方法改写一下,再用逆序对写。(不用太在意重复的数据,因为仅大于才交换)
逆序对用常规的暴力方法 时间杂复度过大,所以这里我用了归并排序来优化

总结

1,数据离散化
2,数组映射
3,逆序对

代码

点击查看代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=100009;
struct data//结构体离散化
{
    ll val;
    ll id;
}olda[N],oldb[N];
ll newa[N],copyy[N],a[N],b[N];
//为了好理解数组开的有点多,写的时候可以省一些
bool cmp(struct data x,struct data y)
{
    return x.val<y.val;
}
ll cnt=0,cup[N];
void merge(ll left,ll right)
{
   if(left>=right)
   {
       return;
   }
    ll mid=(left+right)/2;
    merge(left,mid);
    merge(mid+1,right);
    ll i=left,j=mid+1,k=left;
    while(i<=mid && j<=right)
    {
        if(newa[i]<=newa[j])
        {
            cup[k++]=newa[i++];
        }else
        {
            cup[k++]=newa[j++];
            cnt+=mid-i+1;//与归并排序相比就加了这两条
            cnt=cnt%99999997;
        }
    }
    while(i<=mid)
    {
        cup[k++]=newa[i++];
    }
    while(j<=right)
    {
        cup[k++]=newa[j++];
    }
    for (int v=left;v<=right;v++)
    {
        newa[v]=cup[v];
    }
}

int main()
{
int n;
    scanf("%lld",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%lld",&olda[i].val);
        olda[i].id=i;
    }
    for(int i=1;i<=n;i++)
    {
        scanf("%lld",&oldb[i].val);
        oldb[i].id=i;
    }
    sort(olda+1,olda+1+n,cmp);
    sort(oldb+1,oldb+1+n,cmp);
    for(ll i=1;i<=n;i++)
    {
        a[olda[i].id]=i;
        //不用特判相同时id相等,后面逆序对的处理方向可以避免相等时相交换
        //直接先出现的小
    }
    for(ll i=1;i<=n;i++)
    {
        b[oldb[i].id]=i;
    }
    //假设以b为参照物
    //求逆序对时暴力会超时所以可以进行优化,我用归并优化
    //将第2盒火柴映射为升序,相当于把第二盒当成id为1,2,3,4,5然后把第一盒按id去改
    for(ll i = 1; i <= n; i ++)  copyy[b[i]] = i;//copyy作为按b转化的表,想出这个方法的人真是天才!!
    //将第1盒火柴当对应的元素进行映射为第一种表示
    for(ll i = 1; i <= n; i ++) newa[i] = copyy[a[i]];
    merge(1,n);
    printf("%lld\n",cnt%99999997);
    return 0;
}

标签:ll,排队,mid,数组,火柴,left,逆序
From: https://www.cnblogs.com/butaihuia/p/18639645

相关文章

  • 蓝牛排队助手单机版
    在日常生活中很多时间人们在排队的时候,经常碰到插队,混乱、站立等候等现象.使用蓝牛排队助手可以帮助我们解决在办事过程中所遇到的各种排队、等候和拥挤等现象,让排队显得舒适有序,并且可以大大的提高各个办事处的服务质量和服务形象,为客户及管理人员都带来了方便与愉悦更新日志......
  • 一种基于 M/G/1 排队论模型
    M/G/1排队论模型是一种重要的排队系统模型,广泛应用于各种服务场景中。以下是对该模型的详细解析:一、定义与特点定义:M/G/1排队论模型指的是顾客到达过程服从泊松分布(M),服务时间服从一般分布(G),且只有一个服务台(1)的排队系统。特点:顾客到达是随机的,且相互独立,服从泊松分布。服......
  • 排队算法的matlab仿真,带GUI界面
    1.程序功能描述排队算法的matlab仿真,带GUI界面。分别仿真单队列单服务台,单队列多服务台以及多队列多服务台三种排队方式。2.测试软件版本以及运行结果展示MATLAB2022A版本运行 3.核心程序function[Blocking_Rate,Use_Rate]=func_mms2(Time_Arrival,Time_Server,N......
  • LeetCode题练习与总结:火柴拼正方形--473
    一、题目描述你将得到一个整数数组 matchsticks ,其中 matchsticks[i] 是第 i 个火柴棒的长度。你要用 所有的火柴棍 拼成一个正方形。你 不能折断 任何一根火柴棒,但你可以把它们连在一起,而且每根火柴棒必须 使用一次 。如果你能使这个正方形,则返回 true ,否则返......
  • 排队下单生成自增排序号码的问题场景分析
    今天和同事去地铁口下面的一个面店吃饭,大家桌面扫码后下单,发现自己会有一个取餐号,我的是39,同事的是40多。这当然很容易想到,这个取餐号码是自增的,这种场景再熟悉不过了,在以往我们去饭店吃饭拿到的号因为是在柜台口头下单,服务员扫码支付,所以小票机器打出来的单号就很容易是看的出来......
  • 题解:P11380 [GESP202412 八级] 排队
    题目传送门题意概要有nnn个人排队,其中有mmm对人必须相邻且前......
  • 洛谷 火柴棒等式
    [NOIP2008提高组]火柴棒等式题目描述给你$n$根火柴棍,你可以拼出多少个形如$A+B=C$的等式?等式中的$A$、$B$、$C$是用火柴棍拼出的整数(若该数非零,则最高位不能是$0$)。用火柴棍拼数字$0\sim9$的拼法如图所示:注意:加号与等号各自需要两根火柴棍;如果$A\neqB$,则$A+B......
  • 月入三万的CBD白领,开始在十元奶茶店排队
    文|螳螂观察作者|如意以前的打工人,总把二三十的高价奶茶当成身份的象征,喝上了高价奶茶才能叫做在生活中富养自己。只是,到盘开支的时候,打工人才猛然发觉,动辄二三十一杯的奶茶,不知不觉刮走了好多工资。有小红书网友表示,一年喝奶茶109次,花费3154元。平均单次价值28元。还有人也估......
  • 少儿编程小游戏 | Scratch 火柴人团队冒险:重装上阵
    在线玩:Scratch多人游戏-《火柴人团队冒险:重装上阵》免费下载-小虎鲸Scratch资源站在少儿编程的世界中,团队合作和冒险精神是激发孩子创造力的重要元素。今天我们将为大家介绍一款Scratch平台上的经典少儿编程小游戏——《火柴人团队冒险:重装上阵》。这款游戏不仅带来了团队合......
  • 基于stm32排队系统完整代码分析(二)
    功能代码led1.c、灯#include"led.h"#include"sys.h"voidled_init(void){GPIO_InitTypeDefgpio_initstruct;__HAL_RCC_GPIOB_CLK_ENABLE();gpio_initstruct.Pin=GPIO_PIN_8|GPIO_PIN_9;gpio_initstruct.Mode=GPIO_......