当前位置: 首页 > news >正文

2026ICPC西安邀请赛

https://qoj.ac/contest/3729/problem/17343

题目大意

我们要控制一个机器人走到指定的坐标 (x, y)

  • 指令 0 代表向右走(x+1),1 代表向上走(y+1)。
  • 特殊的 2 可以被替换成 01
  • 指令串会无限循环执行。
  • 目标:把所有的 2 替换掉,使得机器人恰好停在 (x, y),并且最终的字符串字典序最小

初看这道题,最大的难点在于“无限循环”和“两个维度的坐标限制”,极容易让人陷入模拟走路的死胡同。但只要转过弯来,这就是一道披着图论外衣的代数题。

观察题干

我们发现机器人每次移动,要么向右,要么向上。这意味着它每走一步,横纵坐标之和 x + y 就会加 1。

  • 终极推论:机器人走到 (x, y)总步数是绝对固定的,必须恰好是 x + y 步!
  • 整体到局部:既然总步数是 x + y,如果我们强行安排了恰好 x 个向右走的 0,剩下的步数自然全都是向上走的 1我们根本不需要去管 1,只需要盯死 0 的数量即可!

Hint 1:周期与余数分离

总步数固定了,指令串的长度 n 也是固定的。我们直接做除法:

  • 完整执行的轮数k = (x + y) / n
  • 最后一轮多出来的步数m = (x + y) % n

此时,我们可以把原始字符串切成两段来看:

  • A 段(前 m 个字符):这部分指令被机器人走过了 k + 1 次。
  • B 段(剩余 n-m 个字符):这部分指令被走过了 k 次。

Hint 2: 建立方程与贪心求解

假设我们在 A 段里把 u02 变成了 0,在 B 段里把 v02 变成了 0
加上字符串里原本就有的 0,我们要在整个行走过程中凑齐恰好 x0。于是得到一个简单的方程:

(k + 1) * (A段的0总量) + k * (B段的0总量) = x

移项后,我们只需要算出一个剩余目标缺口 (target),使得:

(k + 1) * u0 + k * v0 = target

如何保证字典序最小?
字典序的规则是:越靠前的字符越小越好。因为 A 段永远在 B 段前面,所以我们的贪心策略极其简单:拼命往 A 段塞 0!
我们直接从大到小枚举 A 段能放的 0 的数量(即 u0),一旦算出来的 v0 是合法的(即能被 k 整除,且不超过 B 段拥有的 2 的数量),这就是我们要找的最优解,直接 break!

(注:别忘了特判 k=0 的情况。如果 k=0,说明机器人根本没走到 B 段,B 段全填 0 白嫖一个最小字典序即可。)


代码

点击查看代码
//
// Created by awake on 2026/5/17.
//
#include <bits/stdc++.h>
using namespace std;// clang-format off
struct { auto operator()(auto &i) { cin >> i; } } IN; // NOLINT
struct { auto operator()(auto &i) { cout << i << ' '; } } OUT; // NOLINT
// clang-format on
#define IOS ios::sync_with_stdio(false),cin.tie(nullptr)// NOLINT
// #define int long long
using pii = pair<int, int>; //NOLINT
using ll = long long;       //NOLINT
template <typename T>
using vec = vector<T>; //NOLINT// #define endl '\n'
constexpr int INF = 0x3f3f3f3f;
constexpr int MOD = 998244353;
constexpr int N = 1e6 + 5;
const int K = [] //NOLINT
{random_device rd;return (static_cast<ll>(rd()) << 32) | rd();
}();void solve()
{ll n, x, y;cin >> n >> x >> y;string s;cin >> s;ll S = x + y;ll k = S / n;ll m = S % n;ll A0 = 0, A2 = 0;ll B0 = 0, B2 = 0;for (ll i = 0; i < m; ++i){if (s[i] == '0') A0++;else if (s[i] == '2') A2++;}for (ll i = m; i < n; ++i){if (s[i] == '0') B0++;else if (s[i] == '2') B2++;}ll target = x - (k + 1) * A0 - k * B0;ll best_u0 = -1;ll best_v0 = -1;for (ll u0 = A2; u0 >= 0; --u0){ll rem = target - (k + 1) * u0;if (k > 0){if (rem >= 0 && rem % k == 0){ll v0 = rem / k;if (v0 <= B2){best_u0 = u0;best_v0 = v0;break;}}}else{if (rem == 0){best_u0 = u0;best_v0 = B2;break;}}}if (best_u0 == -1){cout << -1 << "\n";return;}string res = s;ll u_placed = 0;for (ll i = 0; i < m; ++i){if (res[i] == '2'){if (u_placed < best_u0){res[i] = '0';u_placed++;}else{res[i] = '1';}}}ll v_placed = 0;for (ll i = m; i < n; ++i){if (res[i] == '2'){if (v_placed < best_v0){res[i] = '0';v_placed++;}else{res[i] = '1';}}}cout << res << "\n";
}signed main()
{IOS;int T;cin >> T;while (T--)solve();return 0;
}

套路总结

套路一:网格行走中的“步数守恒定律”

  • 特征:题目限定了只能向正方向走(如右和上,或者下和右),且要求到达某个具体坐标。
  • 解法:总步数必然是曼哈顿距离。立刻将二维坐标要求降维成一维计数。只要搞定其中一个维度的数量,另一个维度自然满足。代码里的 if-else 会瞬间少一半。
    这个套路在跳青蛙那道题也出现过https://www.cnblogs.com/butaihuia/p/20065585
    遇到这种题应该优先往总和上想。

套路二:无限循环模式下的“商余分离法”

  • 特征:题目出现“周期性”、“无限循环”、“不断重复直到某条件”的字眼,且数据范围极大(例如本题坐标达到 \(10^{18}\))。
  • 解法:绝不能暴力模拟。立刻算出总需求,然后通过取商 ( / )取模 ( % ),将问题转化为“完整的 \(k\) 圈”加上“最后残缺的 \(m\) 步”。将整体数据拆分为被执行 \(k+1\) 次的前缀,和被执行 \(k\) 次的后缀。

套路三:字典序最小问题的“优先级贪心”

  • 特征:题目不仅要求找出一个解,还要求“字典序最小”或“数值最大/最小”。
  • 解法:将可用资源分为“高权重区”(如本题的 A 段,在字符串最前面)和“低权重区”(B 段)。永远从极致状态开始尝试。比如本题,我们直接倒序枚举 u0(从最大可能值开始),这样碰到的第一个可行解,在数学上绝对是字典序的全局最优解,省去了复杂的全量比较。

http://www.jsqmd.com/news/853865/

相关文章:

  • 动态图学习新范式!Transformer架构革新,统一框架与实战库引领研究新浪潮
  • 不只是安装:深度挖掘Windows Server 2022三大安全功能(安全核心、TLS 1.3、SMB加密)的实战配置
  • P2PNet训练数据预处理实战:用Python脚本快速生成ShanghaiTech等数据集的train.list
  • 2026年APP开发公司推荐指南:国内品牌app定制设计服务商精选 - 新闻快传
  • 团队冲刺第九天
  • 别再连错线了!STM32F103C8T6最小系统板用ST-LINK烧录保姆级教程(含KEIL5配置避坑指南)
  • VSCode装PlatformIO前必看:你的Python环境可能正在‘打架’(附Win10多版本Python清理指南)
  • 2026年四川美容化妆培训学校综合实力评测:5家品牌深度横评 - 资讯速览
  • 【UDS实战】0x85服务:冻结DTC更新,护航ECU程序刷写的幕后功臣
  • 2026年乌鲁木齐家装服务商权威测评及选型指南 - 新闻快传
  • LAMMPS新手避坑指南:如何快速找到并验证你需要的势函数(附NIST等权威库链接)
  • U-Boot分析【学习笔记】(12)
  • 解锁本科论文高效创作新范式 okbiye 智能写作全方位赋能学业撰稿
  • 逆向实战:我是如何一步步“还原”大韩航空官网的Akamai指纹校验逻辑的
  • 构造题
  • 洛谷 P2414 [NOI2011] 阿狸的打字机
  • 蓝桥杯单片机DS18B20温度采集避坑指南:官方驱动文件可能被‘动过手脚’?
  • YOLOv5实战解析——激活函数的选择与调优
  • 单片机IO扩展实战:用74HC595与74HC165构建8x8矩阵键盘的硬件设计与软件消抖
  • 如何在3分钟内搭建Excel MCP Server:无需安装Microsoft Excel的终极指南
  • 华硕笔记本性能管家G-Helper:告别臃肿控制中心,重获系统掌控权
  • 异构计算平台在医疗设备中的应用:FPGA+MPU+MCU三芯合一方案解析
  • 1951-2025年中国1km月平均气温逐年变化量数据集
  • 一文读懂CTF:网络安全领域的_“实战练兵场”,新手入门全指南
  • 【Cheat Engine 7.5】逆向实战:攻克单双精度浮点数内存修改
  • 别再折腾Pico TTS了!2024年Android离线TTS引擎实测:讯飞、Google、ITRI哪个中文效果最好?
  • 用NE555和LM324做个红外倒车雷达:从仿真到焊接,一个模电新手的踩坑实录
  • 新手别慌!拆解一个SMIC 0.18um工艺库,搞懂每个文件夹是干嘛的
  • CTF实战:从ZIP伪加密到二进制文件结构解析
  • 2026年大屏生产厂家深度选型指南:如何为不同场景匹配最佳方案? - 资讯速览