首页 > 其他分享 >【题解】 小狗

【题解】 小狗

时间:2024-08-12 19:16:45浏览次数:11  
标签:tmp ae int 题解 尾部 字符串 bs 小狗

题目描述

【题目描述】
    小 Q 是个爱狗狂魔,他饲养了 N(N<=2000)条中华田园犬狗和 M(M<=2000)条秋田犬。
    并且给每条狗取了一个英文名字,例如:Sally,Sussan,Lysa 等,
    为了方便起见,小 Q 登记时只会登记首字母,例如 Sally、Sussan、Lysa 只会登记为 S、S、L。
    现在中华田园犬和秋田犬分别从左至右各站成了一队。小 Q 准备带他们出去踏青了!
    但因为踏青的路实在太窄,小 Q 不得不在踏青前把两条队伍合成一队。
    那如何合呢?我们假设中华秋田犬所在的队伍为 A 队,秋田犬所在队伍为 B。
    最后合成的新队伍为 C。大家知道的如果从队伍中间选择小狗加入新队伍,容易使原队伍混乱.
    所以现在我们制定如下规则:
        (1)每次从 A 队或者 B 队的头或者尾选取一条小狗加入到新的队伍 C 的尾部去(第一条选择的小狗为头)。
        (2)重复(1)的操作,直到 A 队和 B 队的所有小狗都站到 C 队为止。
    现在小 Q 想知道,按照这种规则,他登记的新队列的最小字典序为多大?
【输入格式】
    第 1 行:两个整数 N 和 M.
    第 2 行至第 N+1 行:每行一个大写字母,表示 A 队中小狗的头字母.
    第 N+2 至 N+1+M 行:每行一个大写字母,表示 B 队中小狗的头字母.
【输出格式】
    一行,得到的最小字典序的序列.
【样例输入】
    3 3
    A
    C
    D
    B
    C
    B
【样例输出】
    ABBCCD
【数据说明】
    50%数据 1<=n,m<=100
    100%数据 1<=n,m<=2000

题目大意

给定2个字符串(有且仅有大写字母组成),每次将任意一个字符串的头部或尾部加入新字符串,求新字符串最小字典序。

思路

设一个字符串为 \(s_1\),另一个字符串为 \(s_2\)。
由于要字典序最小,所以要在 \(s_1\) 的头部、尾部,\(s_2\) 的头部、尾部中找最小的字符加入。

但是,如果其中最小的字符有两个,又该选哪个呢?这时就应该往它们的下一个去看,但是这样一直往后找,就会太复杂。

所以可以给每个字符串建一个反字符串进行比较。例如:原字符串 \(s_1\) 为 \(CBAC\),那么就可以建一个反字符串 \(rs_1\) 为 \(CABC\),因为 \(s_1 < rs_1\),所以选尾部的 \(c\) 显然更优。

但是如果这2个字符串长度不同,就会发生错误。举个例子,字符串 \(s_1\) 为 \(AB\),\(s_2\) 为 \(ABB\)。如果此时按字典序进行比较,则有 \(s1 < s2\),但是先选择 \(s_1\) 显然更优。这时可以比较 $s_1 + s_2 $ 和 \(s_2 + s_1\),就可以实现。

代码

#include <bits/stdc++.h>
using namespace std;

int n, m;
char a[2005], b[2005];
string tmp[6];

int FindMin(int as, int ae, int bs, int be)
{
    tmp[1] = tmp[2] = tmp[3] = tmp[4] = "";
    // tmp[1] 是 字符串a,tmp[2] 是 字符串a的翻转 
    // tmp[3] 是 字符串b,tmp[4] 是 字符串b的翻转  

    for (int i = as, j = ae; i <= ae; i ++ , j -- )
        tmp[1] += a[i], tmp[2] += a[j];
    for (int i = bs, j = be; i <= be; i ++ , j -- )
        tmp[3] += b[i], tmp[4] += b[j];

    int t1 = 1, t2 = 3;
    if (tmp[2] < tmp[1]) t1 = 2; // 相同长度直接比较 
    if (tmp[4] < tmp[3]) t2 = 4; // 相同长度直接比较 

    // 不同长度拼接比较
    if (tmp[t2] == "" || tmp[t1] + tmp[t2] < tmp[t2] + tmp[t1]) return t1;  
    else return t2;
}

int main()
{
    cin >> n >> m;
    for (int i = 1; i <= n; i ++ ) cin >> a[i];
    for (int i = 1; i <= m; i ++ ) cin >> b[i];

    int as = 1, ae = n, bs = 1, be = m; // as、ae 分别是 a 的起始和结束 , bs、be 分别是 b 的起始和结束
    string ans = "";
    for (int i = 1; i <= n + m; i ++ )
    {
        int ret = FindMin(as, ae, bs, be); // 找出选哪边

        // 1 表示 选a的头部,2 表示 选a的尾部 ,3 表示 选b的头部,4 表示 选b的尾部 
        if (ret == 1) ans += a[as ++ ];
        else if (ret == 2) ans += a[ae -- ];
        else if (ret == 3) ans += b[bs ++ ];
        else ans += b[be -- ];
    }

    cout << ans << '\n';

    return 0;
}

标签:tmp,ae,int,题解,尾部,字符串,bs,小狗
From: https://www.cnblogs.com/T-hong/p/18355050

相关文章

  • 题解:NOIP2023 天天爱打卡
    题解:NOIP2023天天爱打卡标签:线段树优化dp先考虑一个朴素的dp,\(f[i]\)表示前\(i\)天,第\(i\)天必打卡能得到的最大能量,有转移:\[f[i]=\max_{j=i-k+1}^{i}(val(j,i)-d\times(i-j+1)+\max_{p=1}^{j-2}f[p])\]\(val(j,i)\)表示第\(j\simi\)天完成的挑战.......
  • [题解]P2292 [HNOI2004] L 语言
    P2292[HNOI2004]L语言注:下文中,\(s[l\simr]\)表示截取字符串\(s\)的第\(l\)个字符到第\(r\)个字符。文字描述的字符串下标从\(1\)开始,但代码实现从\(0\)开始。我们建出AC自动机后,有一个比较暴力的思路。我么用\(f[i]\)表示待查找字符串\(t\)的长度为\(i\)前缀是否满足......
  • AtCoder ABC 366题解
    前言本文部分思路来自于网络,仅供参考。A-Election2题目大意给定两个市长候选人的票数,求结果是否已经确定。解题思路如果剩下的人全部投票给票少的人票少的人也不能赢,则结果就已经确定了。code#include<bits/stdc++.h>usingnamespacestd;intmain(){intn,t,......
  • ABC366D 题解
    第一眼是想写\(kd-tree\)的。然后发现这就是一道三维前缀和的板子题。三维前缀和要想学习三维前缀和,我们首先得了解前缀和的概念,并且学会一维、二维前缀和。什么是前缀和前缀和是容斥原理的典型应用。这种优化方式可以使求和操作的时间复杂度降低到\(O(1)\)(但是需要提前预......
  • 题解:AT_abc351_f [ABC351F] Double Sum
    关于某c人士强制偷袭代码导致AT号被封,\({\color{red}\mathrm{警钟敲碎}}\)。题意一个长\(n\)的数组\(a\),求所有顺序对中两元素之差的和。分析听说有大佬2min切掉。很明显,暴力过不去。考虑计算每个元素的贡献。设\(id\)为该元素之前所有比它小的元素个数,\(sum\)表示这些......
  • tensorboard_logger库无法导入的问题解决
    一、问题描述最近在学习深度学习时,从大神们那里copy的代码中有用到tensorboard_logger这个库的东西,所以很自然地就用condainstall或者pip去安装它,但是结果是:python开源库里面没有这东西。这就让我很苦恼,所以只能自己动手,丰衣足食了。 二、解决方法首先找到tensorboard_logge......
  • ABC366 G - XOR Neighbors 题解
    发现题目实质上就是让你构造一组\(a_{1,2,\dots,n}\),有一些限制,要求一些\(a\)异或起来是\(0\)。看到\(n\le60\),果断列异或方程组,用异或高斯消元。具体地,有\(n\)个方程组,\(a_{i,j}\)表示第\(i\)个方程中\(j\)的系数。对于每一个变量\(i\),要把\(j>i\)的方程中的第......
  • 【题解】P3356 火星探险问题
    \(\large\mathfrak{1st.\Preamble|}\)前言这都什么年代了网络流24题居然还能写题解!个人认为这篇题解讲的还是比较详细的。\(\large\mathfrak{2nd.\Solution|}\)题解看到题目的第一眼,我的反应是这样的:这不跟深海机器人问题差不多吗?Ctrl-CCtrl-V秒了。不过我还是讲讲怎......
  • ABC366D 题解
    Solution题意简述给你一个正整数\(N\)和\(N^3\)个非负整数,表示为\(A_{x,y,z}\)其中\(1\leqx,y,z\leqN\)。您将得到以下格式的\(Q\)个查询,必须按顺序处理。对于第\(i\)次查询\((1\leqi\leqQ)\),您将得到一个整数元组\((Lx_i,Rx_i,Ly_i,Ry_i,Lz_i,......
  • 逆序对数列(P2513) - 题解
    [HAOI2009]逆序对数列原题链接题目描述对于一个数列\(\{a_i\}\),如果有\(i<j\)且\(a_i>a_j\),那么我们称\(a_i\)与\(a_j\)为一对逆序对数。若对于任意一个由\(1\simn\)自然数组成的数列,可以很容易求出有多少个逆序对数。那么逆序对数为\(k\)的这样自然数数列到底......