Codeforces Round 1027 (Div. 3)

news2025/5/31 14:54:07

A. Square Year

题目大意:拆分完全平方数。

【解题】:如果是完全平方数输出0 + 平方根就行,不是就输出-1。

code:

#include <iostream>
#include <string>
#include <cmath>
using namespace std;
typedef long long LL;
#define endl '\n'
void solve() 
{
    string s; cin >> s;
    int t = stoi(s);
    int sq = sqrt(t);
    if(sq * sq != t) cout << -1 << endl;
    else 
    {
        cout << 0 << " " << sq << endl;
    }
}

int main()
{
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int T;
	cin >> T;
	while(T--)
	{
        solve();
	}
	return 0;
}

B. Not Quite a Palindromic String

题目大意:给定一个偶数长度的01序列s,如果si == sn - i+ 1,则称为一对好的索引,问我们能否通过重新调整顺序使得可以构造出一个正好为k对好索引的字符串呢。

【解题】:我们不难发现好索引对的下限minc是尽可能使01配对得来的;上限maxc是通过尽可能00 11 配对得来的。所以k只要在上下限之内就可以,但需要注意k是从下限每次变动两对得来的,因此还要满足k - minc是2的倍数。

code:

#include <iostream>
using namespace std;
typedef long long LL;
#define endl '\n'
void solve() 
{
    int n, k; cin >> n >> k;
    string s; cin >> s;
    int cnt1 = 0, cnt0 = 0;
    for(int i = 0; i < n; i++)
        if(s[i] == '1') cnt1++;
        else cnt0++;
    int minc = abs(cnt1 - cnt0) / 2;
    int maxc = cnt1 / 2 + cnt0 / 2;
    if(k >= minc && k <= maxc && (k - minc) % 2 == 0) cout << "YES" << endl;
    else cout << "NO" << endl;
}

int main()
{
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int T;
	cin >> T;
	while(T--)
	{
        solve();
	}
	return 0;
}

C. Need More Arrays

题目大意:给定非递减顺序排序数组a,我们对数组a进行一下操作:

  • a1 被写入新数组;
  • 如果是 a1+1<a2 ,那么 a2 将被写入一个新数组;否则 a2 将被写入与 a1 相同的数组;
  • 如果是 a2+1<a3 ,那么 a3 会被写入到一个新数组中;否则, a3 会被写入到与 a2 相同的数组中;
  • ...

现在我们可以提前从a中删除任意个数的元素,使得通过上述操作得到的数组数量最多。

【解题】:a是非递减排序的,我们首先考虑是否删除a[1],可以达到最优解,很明显a[1]一定不可以删除,原因是:a[1]一定会形成一个新的数组,而a[2] >= a[1],而在删除a[1],的情况下指挥影响a[2],这就导致了删除a[1],一定会少形成一个新数组。

对于a[i]只会影响a[i + 1],对于一个需要放到与前面元素同一个数组的a[i]来讲:不删可能导致a[i + 1]和a[i]都被放到了与a[i - 1]相同的集合内;删除可能会使a[i + 1] 与a[i - 1] 分开,而删除有对后面没影响。所以最有的贪心策略就是:对于需要放到与前一个元素同一个集合的元素我们就删掉。

code:

#include <iostream>
using namespace std;
typedef long long LL;
#define endl '\n'
void solve() 
{
    int n; cin >> n;
    int cnt = 1;
    int pre; cin >> pre;
    for(int i = 2; i <= n; i++)
    {
        int x; cin >> x;
        if(x - pre > 1) 
        {
            cnt++;
            pre = x;
        }
    }
    cout << cnt << endl;
}

int main()
{
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int T;
	cin >> T;
	while(T--)
	{
        solve();
	}
	return 0;
}

D. Kirei Attacks the Estate

题目大意:给定一个非常大的棋盘,棋盘内有许多怪兽,可以先移动一个怪兽的位置到任意空格置,随后我们需要选择一个矩形包含所有的怪兽,输出最小矩形的大小。

【解题】:不难发现:矩形的大小是由边界点决定的,所以我们以此尝试移动上下左右边界点,就行。但需要注意要是移动边界点没有位置放需要新开一行或一列。

code:

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
typedef long long LL;
#define endl '\n'

const int N = 2e5 + 10;
struct node
{
    LL x, y;
}a[N], b[N];
int n; 
bool cmp1(node& a, node& b)
{
    return a.x < b.x;
}

bool cmp2(node& a, node& b)
{
    return a.y < b.y;
}

LL calc()
{
    LL ans = 4e18;
    LL r = 0, l = 2e9, d = 2e9, u = 0;
    for(int i = 2; i <= n; i++)
    {
        LL x = a[i].x, y = a[i].y;
        l = min(l, x); r = max(r, x);
        d = min(y, d); u = max(u, y);
    }
    LL ret = (abs(r - l) + 1) * (abs(u - d) + 1);
    if(ret == n - 1) ret += min(abs(r - l) + 1, abs(u - d) + 1);
    ans = min(ans, ret);
    r = 0, l = 2e9, d = 2e9, u = 0;
    for(int i = 1; i <= n - 1; i++)
    {
        LL x = a[i].x, y = a[i].y;
        l = min(l, x); r = max(r, x);
        d = min(y, d); u = max(u, y);
    }  
    ret = (abs(r - l) + 1) * (abs(u - d) + 1);
    if(ret == n - 1) ret += min(abs(r - l) + 1, abs(u - d) + 1);
    ans = min(ans, ret);
    r = 0, l = 2e9, d = 2e9, u = 0;
    for(int i = 1; i <= n - 1; i++)
    {
        LL x = b[i].x, y = b[i].y;
        l = min(l, x); r = max(r, x);
        d = min(y, d); u = max(u, y);
    }  
    ret = (abs(r - l) + 1) * (abs(u - d) + 1);
    if(ret == n - 1) ret += min(abs(r - l) + 1, abs(u - d) + 1);
    ans = min(ans, ret);
    r = 0, l = 2e9, d = 2e9, u = 0;
    for(int i = 2; i <= n; i++)
    {
        LL x = b[i].x, y = b[i].y;
        l = min(l, x); r = max(r, x);
        d = min(y, d); u = max(u, y);
    }  
    ret = (abs(r - l) + 1) * (abs(u - d) + 1);
    if(ret == n - 1) ret += min(abs(r - l) + 1, abs(u - d) + 1);
    ans = min(ans, ret);    
    return ans;
}

void solve() 
{
    cin >> n;;

    for(int i = 1; i <= n; i++) 
    {
        cin >> a[i].x >> a[i].y;
        b[i].x = a[i].x;
        b[i].y = a[i].y;
    }
    if(n == 1)
    {
        cout << 1 << endl;
        return;
    }
    sort(a + 1, a + 1 + n, cmp1);
    sort(b + 1, b + 1 + n, cmp2);
    cout << calc() << endl;
}

int main()
{
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int T;
	cin >> T;
	while(T--)
	{
        solve();
	}
	return 0;
}

E. Kirei Attacks the Estate

题目大意:给定一棵树,每个节点有对应权值,要求我们输出每个节点的最大交替和。

节点交替和定义:以该节点为叶节点往上走,加上与该节点距离为偶数节点权值,减去距离为奇数节点权值(大家还是去看人家的定义把吧),这一系列和的最大值。

【解题】:其实我们可以做树上前缀和(交替和),要让该节点的交替和最大就要让它减去一个它前面最小的一个字段(类似于最大字段和)。但是要注意,如果该节点的层数为奇数,那么该节点在做前缀交替和的时候是减,而事实上是加,所有它的前面的值都应该是负的,我们还是常做前缀,输出的时候要输出该节点的前缀交替和减去一个它上面最大的一个前缀交替和的相反数。

code:

#include <iostream>
#include <vector>
#include <cstring>
using namespace std;
typedef long long LL;
const int N = 2e5 + 10;
LL a[N];
vector<int> edg[N];
// pre_max - 该节点前面最大的前缀交替和
// pre_min - 该节点前面最小的前缀交替和
// sum - 根节点到该节点的前缀交替和
// dep - 该节点的深度
LL pre_max[N], pre_min[N], dep[N], sum[N];
void dfs(int child, int fa)
{
    dep[child] = dep[fa] + 1;
    if(dep[child] % 2) sum[child] = sum[fa] + a[child]; 
    else sum[child] = sum[fa] - a[child];
    pre_max[child] = max(sum[child], pre_max[fa]);
    pre_min[child] = min(sum[child], pre_min[fa]);
    for(auto v : edg[child])
    {
        if(v == fa) continue;
        else dfs(v, child);
    }
}

void solve()
{
    int n; cin >> n;
    for(int i = 1; i <= n; i++) 
    {
        pre_max[i] = pre_min[i] = dep[i] = sum[i] = 0;
        edg[i].clear();
        cin >> a[i];
    }
    for(int i = 1; i < n; i++)
    {
        int x, y; cin >> x >> y;
        edg[x].push_back(y);
        edg[y].push_back(x);
    }
    dep[1] = 1;
    dfs(1, -1);
    for(int i = 1; i <= n; i++) 
    {
        // 奇数正常输出前缀减一个最小的
        if(dep[i] % 2) cout << sum[i] - pre_min[i] << " ";
        // 偶数输出前缀减一个最大的的相反数
        else cout << -(sum[i] - pre_max[i]) << " ";
    }
    cout << endl;
}

int main()
{
    int t; cin >> t;
    while(t--)
    {
        solve();
    }
    return 0;
}

F. Small Operations

题目大意:给定三个数x,y,k。可以进行下列操作:

  • 选一个a ,1 <= a <= k ,让x = x * a
  • 选一个a ,1 <= a <= k 且 x % a = 0,让x = x / a

问最小的操作次数使得x = y,如果x 不能变成y输出-1

【解题】:其实不难想到,先把x变成gcd(x, y),然后再从gcd(x, y) 变成y。

问题是怎么求x变成gcd(x, y)的最小次数,他俩之间的倍数是t,就是不断进行操作二,其实就是不断选取1-k的因数累乘凑出t的最少因数个数。这里题解使用dp做的,我cy下来了但不是很懂。

从gcd(x, y) 变成y其实也是凑倍数t,只不过进行的是操作一。

code:

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
typedef long long LL;
#define endl '\n'

LL gcd(LL a, LL b)
{
    return b == 0 ? a : gcd(b, a % b);
}

LL get_ans(LL x, LL k)
{
    if(x == 1) return 0;
    vector<int> fac;
    for(int i = 1; i * i <= x; i++)
    {
        if(x % i == 0) 
        {
            fac.push_back(i);
            if(x / i != i) fac.push_back(x / i);
        }
    }
    sort(fac.begin(), fac.end());
    int n = fac.size();
    vector<int> dp(n, 100);
    dp[0] = 0;
    for(int i = 1; i < n; i++)
    {
        for(int j = i - 1; j >= 0; j--)
        {
            if(fac[i] / fac[j] > k) break;
            else
            {
                if(fac[i] % fac[j] == 0) 
                    dp[i] = min(dp[i], dp[j] + 1);
            }
        }
    }
    return dp[n - 1] == 100 ? -1 : dp[n - 1];
}

void solve() 
{
    LL x, y, k; cin >> x >> y >> k;
    LL g = gcd(x, y);
    LL ans = 0;
    x = x / g;
    y = y / g;
    LL ax = get_ans(x, k);
    LL ay = get_ans(y, k);
    if(ax == -1 || ay == -1) cout << -1 << endl;
    else cout << ax + ay << endl;

}


int main()
{
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int T;
	cin >> T;
	while(T--)
	{
        solve();
	}
	return 0;
}

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

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

相关文章

第五十二节:增强现实基础-简单 AR 应用实现

引言 增强现实(Augmented Reality, AR)是一种将虚拟信息叠加到真实世界的技术,广泛应用于游戏、教育、工业维护等领域。与传统虚拟现实(VR)不同,AR强调虚实结合,用户无需完全沉浸到虚拟环境中。本文将通过Python和OpenCV库,从零开始实现一个基础的AR应用:在检测到特定…

LLaMaFactory 微调QwenCoder模型

步骤一&#xff1a;准备LLamaFactory环境 首先,让我们尝试使用github的方式克隆仓库: git config --global http.sslVerify false && git clone --depth 1 https://github.com/hiyouga/LLaMA-Factory.git # 创建新环境&#xff0c;指定 Python 版本&#xff08;以 3.…

【最新版】Arduino IDE的安装入门Demo

1、背景说明 1、本教程编写日期为2025-5-24 2、Arduino IDE的版本为&#xff1a;Arduino IDE 2.3.6 3、使用的Arduino为Arduino Uno 1、ArduinoIDE的安装 1、下载。网址如下&#xff1a;官网 2、然后一路安装即可。 期间会默认安装相关驱动&#xff0c;默认安装即可。 3、安…

不起火,不爆炸,高速摄像机、数字图像相关DIC技术在动力电池新国标安全性能测试中的应用

2026年7月1日&#xff0c;我国将正式实施GB38031-2025《电动汽车用动力蓄电池安全要求》——这项被称为“史上最严电池安全令”的新国标&#xff0c;首次将“热失控不蔓延、不起火、不爆炸”从企业技术储备上升为强制性要求&#xff0c;标志着电池安全进入“零容忍”时代&#…

thinkadmin中使用layui日期选择器,数据库存储时间戳

form.html <div class="layui-form-item label-required-prev" id="jiezhi_time-div">

WSL中ubuntu通过Windows带代理访问github

WSL中ubuntu通过Windows带代理访问github 前言: WSL是Windows下的ubuntu访问工具&#xff0c;目前无法访问外网&#xff0c;因此需要配置一下。 步骤一 代理中进行如下设置: 步骤二 ubuntu22.04中修改配置 使用如下命令获取IP地址&#xff1a; ip route | grep default | aw…

RISC-V特权模式及切换

1 RISC-V特权模式基本概念 1.1 RISC-V特权模式介绍 RISC-V 指令集架构&#xff08;ISA&#xff09;采用多特权级别设计作为其核心安全机制&#xff0c;通过层次化的权限管理实现系统资源的隔离与保护。该架构明确定义了四个层次化的特权模式&#xff0c;按照权限等级由高至低…

【深度学习】11. Transformer解析: Self-Attention、ELMo、Bert、GPT

Transformer 神经网络 Self-Attention 的提出动机 传统的循环神经网络&#xff08;RNN&#xff09;处理序列信息依赖时间步的先后顺序&#xff0c;无法并行&#xff0c;而且在捕捉长距离依赖关系时存在明显困难。为了解决这些问题&#xff0c;Transformer 引入了 Self-Attent…

4060显卡什么水平 4060显卡参数介绍

NVIDIA的GeForce RTX 40系列显卡基于最新的Ada Lovelace架构&#xff0c;提供了前所未有的图形处理能力和效率。其中&#xff0c;RTX 4060定位中高端市场&#xff0c;针对那些寻求卓越性能同时又注重成本效益的用户群体。那么&#xff0c;4060显卡什么水平呢&#xff1f;本文将…

技术为器,服务为本:AI时代的客服价值重构

在智能化浪潮中&#xff0c;大语言模型的出现为客户服务行业注入了全新动能。然而技术创新的价值不在于技术本身&#xff0c;而在于其赋能服务的深度与广度。AI对于我们来说&#xff0c;如同发动机之于汽车&#xff0c;重要的不是引擎参数&#xff0c;而是整车带给用户的驾驶体…

EasyVoice:开源的文本转语音工具,让文字“开口说话“

名人说&#xff1a;博观而约取&#xff0c;厚积而薄发。——苏轼《稼说送张琥》 创作者&#xff1a;Code_流苏(CSDN)&#xff08;一个喜欢古诗词和编程的Coder&#x1f60a;&#xff09; 目录 一、EasyVoice是什么&#xff1f;1. 核心特性一览2. 技术架构概览 二、安装部署指南…

扫地机产品异物进入吸尘口堵塞异常检测方案

扫地机产品异物进入吸尘口堵塞异常的检测方案 文章目录 扫地机产品异物进入吸尘口堵塞异常的检测方案一.背景二.石头的音频异常检测的方案2.1 音频检测触发点2.1.1时间周期2.1.2根据清洁机器人清扫模式或清扫区域污渍类型,即当清扫模式为深度清洁模式 或清扫区域污渍类型为重度…

C++并集查找

前言 C图论 C算法与数据结构 本博文代码打包下载 基本概念 并查集&#xff08;Union-Find&#xff09;是一种用于处理动态连通性&#xff08;直接或间接相连&#xff09;的数据结构&#xff0c;主要支持两种操作&#xff1a;union 和 find。通过这两个基本操作&#xff0c;可…

git reset --hard HEAD~1与git reset --hard origin/xxx

git reset --hard HEAD~1与git reset --hard origin/xxx git reset --hard origin/xxx有时候会太长&#xff0c;手工输入略微繁琐&#xff0c;可以考虑&#xff1a; git reset --hard HEAD~1 替代。 或者使用这种方式 git reset撤销当前分支所有修改&#xff0c;恢复到最近一…

C++ RB_Tree

一、红黑树是什么&#xff1f;—— 带颜色标记的平衡二叉搜索树 红黑树是一种自平衡二叉搜索树&#xff0c;它在每个节点上增加了一个颜色属性&#xff08;红色或黑色&#xff09;&#xff0c;通过对颜色的约束来确保树的大致平衡。这种平衡策略被称为 "弱平衡"&…

kibana解析Excel文件,生成mapping es导入Excel

一、Excel转为CSV格式 在线免费网站&#xff1a;EXCEL转CSV - 免费在线将EXCEL文件转换成CSV (cdkm.com) 二、登录kibana 点击左边菜单栏找到Machine Learning&#xff0c; 进入后上面菜单选择Data Visualizer&#xff0c;然后上穿转好的csv格式的Excel 点击导入输入建立的m…

开疆智能Profinet转Profibus网关连接EC-CM-P1 PROFIBUS DP从站通讯模块配置案例

本案例是通过开疆智能Profibus转Profinet网关将正弦研发的Profibus从站模块连接的EM600变频器接入到西门子1200PLC的配置案例。 配置过程 1. 打开网关配置软件“”新建项目并添加模块PN2DPM并设置参数 2. 设置网关的Profibus参数。如站地址&#xff0c;波特率等。&#xff08;…

Oracle RMAN自动恢复测试脚本

说明 此恢复测试脚本&#xff0c;基于rman备份脚本文章使用的fullbak.sh做的备份。 数据库将被恢复到RESTORE_LO参数设置的位置。 在恢复完成后&#xff0c;执行一个测试sql,确认数据库恢复完成&#xff0c;数据库备份是好的。恢复测试数据库的参数&#xff0c;比如SGA大小都…

零基础设计模式——结构型模式 - 代理模式

第三部分&#xff1a;结构型模式 - 代理模式 (Proxy Pattern) 在学习了享元模式如何通过共享对象来优化资源使用后&#xff0c;我们来探讨结构型模式的最后一个模式——代理模式。代理模式为另一个对象提供一个替身或占位符以控制对这个对象的访问。 核心思想&#xff1a;为其…

架构意识与性能智慧的双重修炼

架构意识与性能智慧的双重修炼 ——现代软件架构师的核心能力建设指南 作者:蓝葛亮 🎯引言 在当今快速发展的技术环境中,软件架构师面临着前所未有的挑战。随着业务复杂度的不断增长和用户对性能要求的日益严苛,如何在架构设计中平衡功能实现与性能优化,已成为每个技术…