AtCoder Beginner Contest 350

news2024/11/15 21:28:52

前面两道阅读理解直接跳过。

C - Sort

大意

给定一个1 \to n的排列A,你可以执行最多n-1次以下操作,让序列变得有序:

  • 选择两个元素,交换它们的位置。

输出任意可行的操作次数及其对应的操作步骤。

思路

i1 \to n,考虑把i交换到第i位。操作n-1次后必定有序。

pos_i表示元素A_i的位置,每次交换A_i,A_{pos_i}即可。

注意pos的对应位置也要更新。

代码

#include <iostream>
#include <vector>
#include <utility>
using namespace std;
typedef pair<int, int> PII;

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);

    int n;
    cin >> n;

    vector<int> a(n), pos(n);
    vector<PII> ans;

    for(int i = 0, x; i < n; i++){
        cin >> x;
        x--;
        a[i] = x;
        pos[x] = i;
    }
    for(int i = 0; i < n; i++){
        if(a[i] == i) continue;
        ans.push_back({i, pos[i]});
        swap(a[i], a[pos[i]]);
        swap(pos[a[i]], pos[a[pos[i]]]);
    }

    cout << ans.size() << endl;
    for(auto &[x, y]: ans) cout << x + 1 << ' ' << y + 1 << endl;
    return 0;
}

D - New Friends

大意

给定一张无向图,若有三个点x,y,z满足:

  • x,y边相连
  • y,z边相连
  • x,z没有边相连

则用一条边连接x,z,问最多能连多少次边。

思路

最终情况下,一个连通块内的任意两点都会连边,即变成一张完全图。

所以bfs得到每个连通块的点数边数

设第i个连通块有cp_i个点,ce_i条边,则这个连通块对答案的贡献\frac{cp_i \times (cp_i+1)}{2}-ce_i

所有连通块的贡献相加即为答案。

代码

#include <iostream>
#include <queue>
#include <utility>
using namespace std;
#define int long long
typedef pair<int, int> PII;


signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);
    int n, m;
    cin >> n >> m;

    vector<vector<int>> G(n);
    for(int i = 0; i < m; i++){
        int a, b;
        cin >> a >> b;
        a--, b--;
        G[a].push_back(b);
        G[b].push_back(a);
    }

    int ans = 0;
    vector<int> vis(n, false);

    auto bfs = [&](int i){
        queue<int> q;
        q.push(i);

        vis[i] = 1;
        int cp = 1, ce = 0;

        while (q.size()) {
            int u = q.front();
            q.pop();
            for (auto v: G[u]) {
                ce++;
                if (vis[v])
                    continue;
                vis[v] = 1;
                q.push(v);
                cp++;
            }
        }

        return PII(cp, ce);
    };

    for(int i = 0; i < n; i++){
        if(vis[i]) continue;
        auto [cp, ce] = bfs(i);
        ans += cp * (cp - 1) - ce;
    }

    ans /= 2;
    cout << ans << endl;
    return 0;
}

E - Toward 0

大意

给定n,x,y,a,通过两类操作让n变为0

  • n变为\lfloor \frac{n}{a} \rfloor,花费x的代价
  • 掷一个色子,等概率掷出1\to 6中的一个b,将n变为\lfloor \frac{n}{b} \rfloor,花费y的代价

最优情况下,最小期望花费。

思路

考虑dp

根据定义,当前的期望值是所有后继情况的期望值的概率加权

dp_i表示当前数字为i,将其变为0最小期望花费

明显dp_0=0

考虑决策什么,明显是考虑使用操作1还是操作2

两种操作都会产生一个期望值,期望值中最小的,就是最优决策。

需要分别求出操作1的期望花费p_n和操作2的期望花费q_n

  • 执行操作1,后继情况只有dp_{\lfloor \frac{n}{a} \rfloor},因此p_n=dp_{\lfloor \frac{n}{a} \rfloor}
  • 执行操作2,后继情况有六个,分别是dp_{\lfloor \frac{n}{1} \rfloor},dp_{\lfloor \frac{n}{2} \rfloor},dp_{\lfloor \frac{n}{3} \rfloor},dp_{\lfloor \frac{n}{4} \rfloor},dp_{\lfloor \frac{n}{5} \rfloor},dp_{\lfloor \frac{n}{6} \rfloor}
  • 到达每种情况的概率都是\frac{1}{6},可得q_n=\frac{\sum^6_{i=1}dp_{\lfloor \frac{n}{i} \rfloor}}{6} + y
  • 但是上面情况不能构成状态转移方程,因为i=1时会循环求值
  • 我们变一下上面的公式,得到真正的q_n=\frac{\sum^6_{i=2}dp_{\lfloor \frac{n}{i} \rfloor}}{5} + \frac{6}{5}y

得到p_n,q_n后,就可以做决策,dp_n=\min(p_n,q_n)

虽然n \le 10^{18},但是每次都除以i,最多除\log_in次就会变成0,所以总状态数不多,只有O(\log_2n \times \log_3n \times \log_4n \times \log_5n \times \log_6n),不会太大。(大概10^7级别)。

代码

#include <iostream>
#include <unordered_map>
using namespace std;
#define int long long

signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);

    int n, a, x, y;
    cin >> n >> a >> x >> y;

    unordered_map<int, double> dp;

    auto dfs = [&](auto self, int u) -> double{
        if(u == 0) return 0.0;
        if(dp.count(u)) return dp[u];
        double p = self(self, u / a) + x, q = 0.0;

        for(int i = 2; i <= 6; i++) q += self(self, u / i);
        q = q / 5 + (y * 6.0 / 5.0);

        dp[u] = min(p, q);
        return dp[u];
    };
    dfs(dfs, n);
    
    cout.precision(10);
    cout << fixed << dp[n] << endl;
    return 0;
}

F - Transpose

大意

给定一个字符串S,其中包括括号和大小写字母

依次处理每个匹配的括号里的字符,将其左右颠倒,并将大小写字母变换

问最终的字符串。

思路

首先设P_i表示S_i对应括号的另一个端点的编号。使用括号匹配的方法预处理出P

由于题目中的操作是反反得正的(不考虑括号来说),例如\texttt{((abc))} \to \texttt{(CBA)} \to \texttt{abc},所以我们可以预先确定字符的大小写:

  • 括号深度为偶数的字符不会大小写反转。
  • 括号深度为奇数的字符则大小写反转。

根据这一点提前交换字母的大小写,就无需再考虑字母的大小写了。

这样我们就简化了问题,接下来设f(l,r,d)S_{l\cdots r}按要求处理后的答案(d表示正序或反序)。

那么就可以按d表示的顺序输出S_{l\cdots r}中的字符,遇到形如\texttt{(...)}的子串递归处理即可。

注意反序处理时,遇到的是右括号

Q&A

如何找到形如(...)的子串?

在已经预处理P的情况下:

  • 如果是正序处理,那么当 S_i = \texttt{(} 时,就可以找到一个范围为[i,P_i]子串
  • 如果是反序处理,那么当 S_i = \texttt{)} 时,就可以找到一个范围为[P_i,i]子串

这就说明了上文的最后一句话。

其他需要注意的点

注意递归调用时不能带上括号,同时d要取反。

而且遇到(...)子串时,需要处理完子串后才能继续处理下一个字符

例如:

  • 正序:应调用f(i+1,P_i-1,1)
  • 反序:应调用f(P_i+1,i-1,0)

d取反是因为反序的时候,(...)子串内的字符需要维持和外面相反的顺序。正序同理。

代码

#include <iostream>
#include <vector>
using namespace std;
int main(){
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);

    string s;
    cin >> s;

    int n = s.size();
    vector<int> mch(n, -1), stk;

    auto flip = [&](char c) -> char{
        if(c >= 'A' && c <= 'Z') return tolower(c);
        return toupper(c);
    };

    int dep = 0;
    for(int i = 0; i < n; i++){
        if(s[i] == '('){
            stk.push_back(i);
            dep++;
        }
        else if(s[i] == ')'){
            int f = stk.back();
            mch[i] = f; mch[f] = i;
            stk.pop_back();
            dep--;
        }else if(dep & 1) s[i] = flip(s[i]);
    }

    string ans;

    auto dfs = [&](auto self, int l, int r, int d) -> void{
        if(d == 0){
            while(l <= r){
                if(s[l] == '('){
                    self(self, l + 1, mch[l] - 1, 1);
                    l = mch[l];
                }else ans.push_back(s[l]);
                l++;
            }
        }else{
            while(l <= r){
                if(s[r] == ')'){
                    self(self, mch[r] + 1, r - 1, 0);
                    r = mch[r];
                }else ans.push_back(s[r]);
                r--;
            }
        }
    };

    dfs(dfs, 0, n - 1, 0);
    cout << ans << endl;
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1612505.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

机器学习中的过拟合问题及应对策略:深入剖析与实战指南

在机器学习的领域中&#xff0c;过拟合是一个普遍而又棘手的问题。过拟合指的是模型在训练数据上表现优秀&#xff0c;但在未知或测试数据上表现不佳的现象。这通常是因为模型过于复杂&#xff0c;以至于“记住”了训练数据的噪声和细节&#xff0c;而非学习其内在规律和结构。…

互连芯片浪潮席卷AI服务器:突破瓶颈,再创辉煌

改变AI服务器&#xff1a;互连芯片技术创新和突破 AI服务器崛起&#xff0c;引领未来创新根据TrendForce数据&#xff0c;AI服务器出货量达130,000台&#xff0c;占服务器总出货量的1%。主要制造商推出生成式AI产品&#xff0c;推动订单激增。ChatGPT等应用的需求持续增长&…

windows ubuntu 子系统:肿瘤全外篇,2. fq 数据质控,比对。

目录 1.质控 2.比对并排序 3.标记PCR重复,使用picard 4.samtools建立索引 首先我们先下载一组全外显子测序数据。nabi sra库&#xff0c;随机找了一个。 来自受试者“16177_CCPM_1300019”(SRR28391647, SRR28398576)的样本“16177_CCPM_1300019_BB5”的基因组DNA配对端文库…

VisionPro 脚本教程专栏:深入理解与实践

文章目录 VisionPro 脚本教程专栏&#xff1a;深入理解与实践。目录1. 脚本简介1.1 VisionPro 项目组成1.2 脚本的作用 2. 脚本类与方法2.1 ToolGroup 脚本类2.2 ToolBlock 脚本类2.3 Job 脚本类 3. 脚本使用案例3.1 Job脚本&#xff1a;自动调节曝光时间3.2 ToolBlock脚本&…

C++:面向对象三大特性之一:继承

继承 1.继承理解2.继承方式引起访问变化表格表格理解 3.赋值转换1.普通对象赋值2.继承对象赋值&#xff1a;赋值转换注意 4.继承的作用域5.派生类默认成员函数1.构造函数2.析构函数3.拷贝构造4.赋值重载 6.继承与友元7.继承与静态成员 1.继承理解 继承机制是面向对象程序设计使…

驶向成功:如何选择适合国际拓展的完美CRM

一、出海企业应该怎么选择CRM&#xff1f; 出海企业在选择CRM系统时&#xff0c;需要考虑行业特性以及在对外业务过程中可能遇到的问题。接触了一些出海企业客户&#xff0c;总结了以下出海企业在选择CRM时的诉求。 1、合法合规风险 出海企业的业务遍布不同国家地区&#xff…

【考研数学】基础跟武忠祥,同步刷《660》的正确方法

听我的&#xff0c;现在立刻马上停下来 你这不是在做题&#xff0c;你这是在看题&#xff0c;效果最差的那种&#xff0c;做完过两天就忘的一干二净了 我不敢说我特别会学习考研数学&#xff0c;但是我考研的时候&#xff0c;最后数学一的成绩是120&#xff0c;不算特别好&am…

搞定这些python自动化测试面试题与答案汇总,offer拿到手软!

1、什么项目适合做自动化测试&#xff1f; 关键字&#xff1a;不变的、重复的、规范的 1&#xff09;任务测试明确&#xff0c;需求不会频繁变动 2&#xff09;项目周期要足够长 3&#xff09;自动化测试脚本可重复使用&#xff0c;比如&#xff1a;比较频繁的回归测试 4&…

01-大语言模型发展

AI大模型的相关的一些基础知识&#xff0c;一些背景和基础知识。 多模型强应用AI 2.0时代应用开发者的机会。 0 大纲 AI产业的拆解和常见名词应用级开发者&#xff0c;在目前这样一个大背景下的一个职业上面的一些机会实战部分的&#xff0c;做这个agent&#xff0c;即所谓智…

基于pytest自动化测试框架分享

一、pytest运行方式与基本规范 1.简单介绍 pytest是一个非常成熟的全功能的Python测试框架&#xff0c;主要有以下几个特点&#xff1a; 简单灵活&#xff0c;容易上手支持参数化能够支持简单的单元测试和复杂的功能测试&#xff0c;还可以用来做Web UI自动化测试&#xff0…

第 7 章 导航实现(自学二刷笔记)

重要参考&#xff1a; 课程链接:https://www.bilibili.com/video/BV1Ci4y1L7ZZ 讲义链接:Introduction Autolabor-ROS机器人入门课程《ROS理论与实践》零基础教程 准备工作 请先安装相关的ROS功能包&#xff1a; 安装 gmapping 包(用于构建地图)&#xff1a; sudo apt inst…

详细UI色彩搭配方案分享

UI 配色是设计一个成功的用户界面的关键之一。UI 配色需要考虑品牌标志、用户感受、应用程序的使用场景&#xff0c;这样可以帮助你创建一个有吸引力、易于使用的应用程序。本文将分享 UI 配色的相关知识&#xff0c;帮助设计师快速构建 UI 配色方案&#xff0c;以满足企业的需…

webgl canvas系列——animation中基本旋转、平移、缩放(模拟冒泡排序过程)

文章目录 ⭐前言⭐canvas绘制图片&#x1f496;状态保存和恢复&#x1f496;移动、旋转、缩放、变形&#x1f496;移动绘制一个渐变的box&#x1f496;旋转&#x1f496;缩放 ⭐模拟冒泡排序过程⭐结束 ⭐前言 大家好&#xff0c;我是yma16&#xff0c;本文分享webgl canvas系…

EMD分解

ref&#xff1a;【EMD经验模态分解-哔哩哔哩】 https://b23.tv/LfepZjU 流程&#xff1a; IMF 固有模态函数 imf1 迭代直到是一个imf 8次迭代后&#xff0c;满足是一个imf residual的得到&#xff1a;原始信号-均值&#xff08;上下包络线的均值&#xff09; imf2 为什么时序…

【公司UI自动化学习】

公司课程链接&#xff1a;https://l.jd.com/student/project/project.du?project_id697509403 公司的课程&#xff0c;是给一个学习方向。 一、 PC自动化 1&#xff09;什么项目适合 2&#xff09;PC自动化介入时间点 3&#xff09;自动化率&#xff1a; 频繁改动的&…

【Harmony3.1/4.0】笔记二

概述 列表是一种复杂的容器&#xff0c;当列表项达到一定数量&#xff0c;内容超过屏幕大小时&#xff0c;可以自动提供滚动功能。它适合用于呈现同类数据类型或数据类型集&#xff0c;例如图片和文本。在列表中显示数据集合是许多应用程序中的常见要求&#xff08;如通讯录、…

深度学习500问——Chapter08:目标检测(2)

文章目录 8.2.4 R-FCN 8.2.5 FPN 8.2.6 Mask R-CNN 8.2.4 R-FCN R-FCN 有哪些创新点 R-FCN仍然属于two-stage目标检测算法&#xff1a;RPN R-FCN Fully convolutional位置敏感得分图&#xff08;position-sentive score maps&#xff09; our region-based detector is ful…

java-Spring-入门学习-第二天(单例模式和多例模式)

目录 Bean作用域 单例模式(默认可以不写) Spring下的 AutoWired 依赖注入 JaveEE下的 Resource 依赖注入 多例模式 Bean作用域 ​在Spring框架中&#xff0c;Bean是按照作用域来创建的&#xff0c;常见的作用域有两种&#xff1a;Singleton 和 Prototype。Singleton (单例…

6.SpringBoot 日志文件

文章目录 1.日志概述2.日志作用3.使用和观察日志3.1如何观察日志3.2使用日志3.3日志级别3.4日志持久化3.5日志分割 4.日志框架4.1门面模式(外观模式)4.2 SLF4J框架介绍4.3 日志格式的说明4.3.1日志名称 5.日志颜色设置6.总结 大家好&#xff0c;我是晓星航。今天为大家带来的是…

【Java】HashMap、HashTable和ConcurrentHashMap的区别

文章目录 区别一、HashMap1.1基本定义与特性1.2工作原理与实现1.3常用方法1.4性能与优化 二、HashTable三、ConcurrentHashMap3.1基本特点3.2实现原理3.3常用方法3.4适用场景3.5性能优化 HashTable、HashMap和ConcurrentHashMap之间的区别主要体现在线程安全、继承关系与实现接…