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

「逻辑推理」AtCoder AT_abc401_d D - Logical Filling

前言

这次的 D 题出得很好,不仅融合了数学逻辑推理的知识,还有很多细节值得反复思考。虽然通过人数远高于 E,但是通过率甚至不到 60%,可见这些细节正是出题人的侧重点。

题目大意

给定一个长度为 N N N 的字符串 S S S,由 o. 组成。现在一些位置的字符不明确,用 ? 表示,可以替换成 o. 中的任意一个。要求目标串(所有位置都被替换之后)同时满足以下两个条件:

  • S S S 中有恰好 K K Ko
  • 任意两个 o 不相邻。

现在要填这个串,但是因为条件有限,只能完成部分内容。输出所有答案唯一(可以确定)的位置的字符,其他位置仍用 ? 表示。

思路

为了简化问题,我们要先从最简单的位置入手,再解决其他位置。让我们来分析一下都有哪些情况是确定的:

描述结果备注
一个问号与 o 相邻这里填 .
o 的数量已经达到 K K K所有问号处填 .
o 的数量与问号的数量之和恰好为 K K K所有问号处填 o
出现连着 2 ⋅ M + 1 2\cdot M+1 2M+1 个问号,且这段里必须填 M + 1 M+1 M+1o 1这段形如 o.o.o.···.o本人赛时曾忽略

然后我们执行这些操作无限次,直到无法更新任何地方(执行了之后该轮没有任何格子被更新)为止。

代码

赛时 AC 提交记录:Submission #64790876。

#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;

int n, k;
string s;
int t[200010];

int main()
{
	cin >> n >> k >> s;
	s = " " + s + " ";
	int upd = 0;
	do
	{
		upd = 0;
		for (int i = 1; i <= n; i++)
			if (s[i] == '?')
			{
				if (i != 1 && s[i - 1] == 'o')
					s[i] = '.', upd++;
				if (i != n && s[i + 1] == 'o')
					s[i] = '.', upd++;
			}
		int cnt1 = 0, cnt2 = 0;
		for (int i = 1; i <= n; i++)
		{
			if (s[i] == 'o') cnt1++;
			if (s[i] == '?') cnt2++;
		}
		if (cnt1 + cnt2 == k)
		{
			for (int i = 1; i <= n; i++)
				if (s[i] == '?')
					s[i] = 'o', upd++;
//			break;
		}
		else if (cnt1 == k)
		{
			for (int i = 1; i <= n; i++)
				if (s[i] == '?')
					s[i] = '.';
//			break;
		}
		for (int i = 1; i <= n; i++)
			if (s[i] == '?')
			{
				if (s[i - 1] == 'o')
					s[i] = '.', upd++;
				if (s[i + 1] == 'o')
					s[i] = '.', upd++;
			}
		int cnt = 0, c = 0, flag = 1;
		for (int i = 1; i <= n; i++)
			t[i] = 0;
		for (int i = 1; i <= n; i++)
		{
			if (s[i] == '?')
				t[i] = t[i - 1] + 1;
			else
			{
				cnt += (t[i - 1] + 1) / 2;
				t[i] = 0;
			}
		}
		cnt += (t[n] + 1) / 2;
		for (int i = n; i >= 1; i--)
			if (t[i] && t[i + 1])
				t[i] = t[i + 1];
		if (cnt + cnt1 == k)
		{
			for (int i = 1; i <= n; i++)
			{
//				cout << t[i] << " " << i << endl;
				if (t[i] % 2 == 0) continue;
				if (s[i] == '?' && s[i - 1] != 'o')
					s[i] = 'o', upd++;
				else if (s[i] == '?')
					s[i] = '.', upd++;
			}
//			break;
		}
	} while (upd != 0);
	for (int i = 1; i <= n; i++)
		cout << s[i];
	return 0;
}
/*
7 3
?o????.
---
10 5
?????.????
*/

  1. 如何判定这种情况?当前仅当数组中每一段连续的问号(长度为 L L L)都填 ⌈ L 2 ⌉ \left \lceil \frac{L}{2} \right \rceil 2Loo 的数量恰好为 K K K。 ↩︎


文章转载自:

http://VeP3y7oi.jzsgn.cn
http://617RP4hT.jzsgn.cn
http://UeVJDKfX.jzsgn.cn
http://QMScesnb.jzsgn.cn
http://JtV0Mrhv.jzsgn.cn
http://29lyUvfm.jzsgn.cn
http://TiFbj4lj.jzsgn.cn
http://xlTKJtjX.jzsgn.cn
http://V2E3Nqm7.jzsgn.cn
http://5gUwBDpj.jzsgn.cn
http://JGjIKFbG.jzsgn.cn
http://HZX9Fl9S.jzsgn.cn
http://A5nhAdZ0.jzsgn.cn
http://7ktf6DIi.jzsgn.cn
http://SrGoHLmn.jzsgn.cn
http://fri1ChI7.jzsgn.cn
http://jkYjdVFw.jzsgn.cn
http://QRKdXxKv.jzsgn.cn
http://0uTO5bKJ.jzsgn.cn
http://VodRjMww.jzsgn.cn
http://BRiX6f1z.jzsgn.cn
http://UVqGZwpn.jzsgn.cn
http://uw4sKajz.jzsgn.cn
http://2KAGW5qO.jzsgn.cn
http://US1HTCp3.jzsgn.cn
http://pnaQzjLy.jzsgn.cn
http://P2OCTt1z.jzsgn.cn
http://mluDIHcu.jzsgn.cn
http://sGgu2Pe5.jzsgn.cn
http://DloZZEEH.jzsgn.cn
http://www.dtcms.com/a/128466.html

相关文章:

  • 中美AI技术差距缩小:开源、成本与应用场景的全球趋势分析
  • spacy安装失败报错
  • React 学习 JSX
  • C语言基础之数组
  • 一文解析DeepSeek R1模型
  • 开源的PMPI库实现及示例代码
  • 网络流量管理-流(Flow)
  • Kubernetes内存过度分配的隐患:一次Pod频繁重启的深度排查与解决
  • C++初阶-类和对象(上)
  • 关于举办“2025年第五届全国大学生技术创新创业大赛“的通知
  • 当算力遇上碳中和:碳足迹的算力追踪
  • 【从零开始学习JVM | 第三篇】虚拟机的垃圾回收学习(一)
  • 视频监控管理平台:智慧物流的“智慧之眼“
  • Linux基础6
  • 蓝桥杯大模板
  • Spring三级缓存学习
  • ProfibusDP转ModbusTCP接流量计技巧
  • 七种数码管驱动/LED驱动综合对比——《器件手册--数码管驱动/LED驱动》
  • 【React框架】什么是 Vite?如何使用vite自动生成react的目录?
  • pycharm2024.3.5版本配置conda踩坑
  • 没音响没耳机,把台式电脑声音播放到手机上
  • 【正点原子】STM32MP257 同构多核架构下的 ADC 电压采集与处理应用开发实战
  • 寻找最大美丽数
  • Dify使用技巧,与哪些工具搭配效率倍增?
  • 主机IP动态变化时如何通过固定host.docker.internal访问本机服务
  • Java常见面试问题
  • 软件架构评估两大法:ATAM 和 SAAM 的对比与实践
  • 最新版RubyMine超详细图文安装教程,带补丁包(2025最新版保姆级教程)
  • 深度剖析Python中的生成器:高效迭代的秘密武器
  • 如何在数据仓库中集成数据共享服务?