惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Microsoft Azure Blog
Microsoft Azure Blog
aimingoo的专栏
aimingoo的专栏
F
Fortinet All Blogs
Blog — PlanetScale
Blog — PlanetScale
GbyAI
GbyAI
MongoDB | Blog
MongoDB | Blog
月光博客
月光博客
The Cloudflare Blog
量子位
T
Tailwind CSS Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
B
Blog
MyScale Blog
MyScale Blog
T
The Blog of Author Tim Ferriss
The GitHub Blog
The GitHub Blog
G
Google Developers Blog
D
DataBreaches.Net
V
Visual Studio Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Last Week in AI
Last Week in AI
U
Unit 42
博客园 - 聂微东
有赞技术团队
有赞技术团队
A
About on SuperTechFans

博客园_首页

Plist 二进制格式 Milvus 和 PGVector,哪个更好? OpenClaw 已过时?在 VS Code 中运行 Hermes Agent! 第30篇文章:一个大三计科生的自白 Manim如何在数学公式中完美显示中文? Docker 部署 RocketMQ 5 并发编程核心概念辨析 C#事务处理最佳实践:别再让“主表存了、明细丢了”的破事发生 CLI 是什么?为什么大厂突然集体卷命令行? 【从0到1构建一个ClaudeAgent】协作-自主Agent UIImageView 设置图片不生效的原因排查 最小二乘问题详解20:无先验约束下的增量式SFM自由网平差 痞子衡嵌入式:大话双核i.MXRT1180之XIP应用里借助MU实现可靠Flash IAP的方法 AI Chat 封装, SemanticKerne.AiProvider.Unified 已发布 Windows下右键编辑js文件无法打开记事本——在注册表中使用环境变量 在后台服务中使用 Scoped 服务,为什么总是报错? H200 安装驱动并使用sglang启动模型 wireshark 抓包Trap上报告警内容 我用 AI 辅助开发了一系列小工具(2):图片压缩工具 [A Primer On MC and CC] 2.1 Memory Consistency 1 - 指令重排序和 SC 模型 Oracle数据库SCN推进技术详解与实践指南 玩转控件:封装个带图片的Label控件 Claude Code 4.7 真正该升级的不是模型,而是你的工作流 前端小白一句话,AI 帮我做了个颜值拉满的桌面媒体播放器。当代码不再是门槛,一句话编程就是现实。 5. WorkBuddy: 小龙虾的灵魂三件套,让你的小龙虾不只是工具 SQLite 分片方案实战:三种分片策略的深度对比 告别简陋 UI!一款基于 Fluent Design 和基于 WinUI 的开源免费、现代化的 Avalonia UI 控件库 关于二进制排列组合枚举的总结 AI开发-python-LangGraph框架(3-27-LangGraph从零实现大模型智能决策工作流) ElasticSearch主分片和副本分片概念详解
P13735 [JOIGST 2025] 魔法阵 / Magic Circle 题解
huan9178 · 2026-05-06 · via 博客园_首页

题目链接

P13735 [JOIGST 2025] 魔法阵 / Magic Circle

题目描述

比太郎所在的魔法学校即将举办运动会。运动会中有一个项目,称为“魔法阵”。

\(N\) 个魔法阵依次排列在一个圆上,顺时针编号为 \(1\)\(N\)。每个魔法阵为红色或蓝色中的一种,使用长度为 \(N\) 且仅包含小写字母 br 字符串 \(S\) 表示:\(S_j(1\le j\le N)\)r 则表示魔法阵 \(j\) 为红色,否则为蓝色。

比太郎可以通过如下的两种方式在魔法阵中传送:

  • 选择一个相邻的魔法阵,花费 \(1\) 秒传送过去。换句话说,可以在魔法阵 \(j(1\le j\le N-1)\)\(j+1\) 间传送(两个方向均可),也可以在魔法阵 \(1\)\(N\) 间传送(两个方向均可);
  • 选择一个与当前所在魔法阵颜色相同的魔法阵(不一定要相邻),花费 \(1\) 秒传送过去。

目前他仅得知每个魔法阵的颜色,但并不知道运动会当天具体的传送计划。于是他决定考虑 \(Q\) 个传送计划:在第 \(i\) 个计划中,他要从魔法阵 \(X_i\) 开始,花费最少的时间传送到魔法阵 \(Y_i\)

请你对于每一个传送计划,求出最少需要花费的时间。

输入格式

第一行输入两个整数 \(N,Q\)

第二行输入一个字符串 \(S\)

接下来 \(Q\) 行,每行输入两个整数 \(X_i,Y_i\)

输出格式

输出 \(Q\) 行,在第 \(i\) 行输出一个整数,表示第 \(i\) 个传送计划最少需要花费的传送时间(单位:秒)。

输入输出样例 #1

输入 #1

5 2
rbrbb
5 3
4 5

输出 #1

2
1

输入输出样例 #2

输入 #2

4 3
brrr
2 4
1 3
3 1

输出 #2

1
2
2

输入输出样例 #3

输入 #3

6 3
brbrbr
1 2
2 5
2 4

输出 #3

1
2
1

输入输出样例 #4

输入 #4

6 5
bbbrrr
2 3
2 4
2 5
2 6
2 1

输出 #4

1
2
3
2
1

说明/提示

【样例解释 #1】

在此样例中,魔法阵的颜色分别为红色、蓝色、红色、蓝色、蓝色。

对于第一组计划(\(5\to 3\)),比太郎可以使用如下传送方案:

  1. 从魔法阵 \(5\) 传送到相邻的魔法阵 \(1\),花费 \(1\) 秒;
  2. 从魔法阵 \(1\) 传送到颜色相同的魔法阵 \(3\),花费 \(1\) 秒。

最少需要花费的时间为 \(2\) 秒。可以证明不可能在小于 \(2\) 秒的时间内从魔法阵 \(5\) 传送到魔法阵 \(3\)

对于第二组计划(\(4\to 5\)),比太郎可以使用如下传送方案:

  1. 从魔法阵 \(4\) 传送到颜色相同的魔法阵 \(5\),花费 \(1\) 秒。

最少需要花费的时间为 \(1\) 秒。

该样例满足子任务 \(5,6\) 的限制。

【样例解释 #2】

该样例满足子任务 \(2,5,6\) 的限制。

【样例解释 #3】

该样例满足子任务 \(3,5,6\) 的限制。

【样例解释 #4】

该样例满足子任务 \(4,5,6\) 的限制。

【数据范围】

  • \(3\le N\le 5\times 10^5\)
  • \(1\le Q\le 5\times 10^5\)
  • \(S\) 为仅包含小写字母 br 的长度为 \(N\) 的字符串;
  • \(1\le X_i,Y_i\le N(1\le i\le Q)\)
  • \(X_i\ne Y_i(1\le i\le Q)\)

【子任务】

  1. \(6\) 分)\(N=3\)\(Q\le 100\)
  2. \(13\) 分)\(S_1\)b\(S\) 的其他字符均为 r
  3. \(18\) 分)\(N\) 为偶数,\(S\) 奇数位置的字符为 b,偶数位置的字符为 r
  4. \(23\) 分)\(N\) 为偶数,\(S\) 的前 \(\frac{N}{2}\) 个字符为 b,后 \(\frac{N}{2}\) 个字符为 r
  5. \(21\) 分)\(N,Q\le 100\)
  6. \(19\) 分)无附加限制。

题解

题意

给出一个含有 N 个点的圆,每个点为红色蓝色,使用相邻传送同色传送,求出从点 x 至点 y 的最少传送次数。

思路

  • \(X_i\ne Y_i(1\le i\le Q)\)

至少也要传送一次
所以有两种情况:

  1. 颜色相同 || 魔法阵\(X_i\)和魔法阵\(Y_i\)相邻
    那么直接同色传送就行,输出1。
  2. 颜色不同 && 魔法阵\(X_i\)和魔法阵\(Y_i\)不相邻
    那么在圆上必定存在两种不同颜色相邻,可以从魔法阵\(X_i\)同色传送到其中一个,相邻传送到另一个,再同色传送到魔法阵\(Y_i\)。所以最多3次。
    直接用if大法分类讨论一下就行。(魔法阵\(X_i\)或魔法阵\(Y_i\)与不同颜色魔法阵相邻就输出2,否则输出3)

AC代码:

#include<bits/stdc++.h>
using namespace std;
int main(){
	int n,q,i,x,y,s,b,sum;
	string a;
	cin>>n>>q;
	cin>>a;
	a=" "+a;
	for(;q>0;q--){
		cin>>x>>y;
		if(a[x]==a[y]||abs(x-y)==1||abs(x-y)==n-1){
			cout<<1<<'\n';
			continue;
		}
		s=y-1,b=y+1;
		if(s<1)
			s=n;///////注意魔法阵依次排列在一个圆上,首尾相连,要注意边界
		if(b>n)
			b=1;
		if(a[s]==a[x]||a[b]==a[x]){
			cout<<2<<'\n';
			continue;
		}
		s=x-1,b=x+1;
		if(s<1)
			s=n;
		if(b>n)
			b=1;
		if(a[s]==a[y]||a[b]==a[y]){
			cout<<2<<'\n';
			continue;
		}
		cout<<3<<'\n';
	}
	return 0;
}