E - Stamp
题目链接 : E - Stamp (atcoder.jp)
题意:给定长为n的s串,m的t串,和一个长度为n的x串,问你能否操作任意次数的操作, 每次操作都可以使x中长度为m的存在串变为t,最后使得变为n
赛时没过,赛后有人发了原题,936. 戳印序列 - 力扣(LeetCode),看了很久的题解,发现做法太巧妙了,把字符串转化为(图论)拓扑图,属实想不到, 最后还能求出可以操作哪些位置
思路:因为前面的操作会影响后面的操作,所以要考虑倒推
本文采用类似于拓扑排序的思想。
我们记字母印章长度为 m ,目标字符串长度为 n 。我们拿字母印章在目标字符串上进行滑动,那么在目标字符串中总共将会有 n−m+1 个窗口。另外,我们将逆序操作过程中所得到的各窗口的起始端点值记录在列表 res 中,最后只需将 res 反转即可得到答案。
那么我们可以将本题和拓扑排序的相关概念进行映射:
>「入度」:每个窗口中对应字符不相同的总数,起始默认为 m。当入度为 0 时,说明这个窗口的所有字符都与目标字符串相对应,我们就可以把这个窗口放入到队列(不一定是 vector 的队列,任意容器均可, deque也可以)中。
>「边」:对于目标字符串的每个位置上,有不一致字符的窗口。我们用邻接表的方式存储边,如果一个滑动窗口的某一个字符与目标字符串不一致,那么我们就连一条边。
至此,我们通过拓扑排序,就可以得到最终的结果了:
1.遍历一遍所有的窗口,如果该位置上的字符与目标字符不一致,那么我们在邻接表中连接一条边;相反如果字符一致,那么该窗口的入度减 1。
2.当某个窗口的入度为 0 时,那么这个窗口的所有字符都与目标字符串相对应,我们可以将该窗口的起始端点放入到队列中。
3.将队列中的窗口依次出队,每次出队时,我们在 res 列表中记录该窗口的起始端点。
4.我们可以想象该窗口中的字符全部替换为 '#' ,表示可以匹配任意字符。那么我们可以从邻接表中将之前与该位置不同的窗口的入度都减 1。
5.重复(2),直到队列为空。
6.当队列为空时,判断 res 的长度是否与 n−m+1 相等,相等则完成了拓扑排序;不相等则说明无法印出目标字符串。
7.如果完成了拓扑排序,那么 res 的长度一定是符合题目要求,我们只需返回逆序的 res 即可(逆序分析)。相反,我们返回一个空容器。最后根据容器大小ac这道题
ac代码
// Problem: E - Stamp
// Contest: AtCoder - Sky Inc, Programming Contest 2023(AtCoder Beginner Contest 329)
// URL: https://atcoder.jp/contests/abc329/tasks/abc329_e
// Memory Limit: 1024 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org) #include<bits/stdc++.h> using namespace std;
using ull = unsigned long long;
using ll = long long;
using PII = pair<int,int>;
#define IOS ios::sync_with_stdio(false),cin.tie(0)
#define endl "\n"
#define pb push_back
const int N=1e5+10;
const int INF=0x3f3f3f3f;
const int mod=998244353; void solve()
{
int n, m; cin >> n >> m;
string s, t; cin >> s >> t;
vector<vector<int>> g(n);
vector<int> ind(n - m + 1, m);
vector<int> q;
vector<bool> st(n);
for(int i = 0; i < n - m + 1; i ++)
{
for(int j = 0; j < m; j ++)
{
if(s[i + j] == t[j])
{
ind[i] --;
if(ind[i] == 0) q.pb(i);
}
else
g[i + j].pb(i);
}
}
vector<int> res;
while(q.size())
{
int u = q.back(); q.pop_back();
res.pb(u);
for(int i = 0; i < m; i ++)
{
if(st[u + i]) continue;
st[u + i] = true;
for(auto &&v : g[u + i])
{
ind[v] --;
if(ind[v] == 0) q.pb(v);//插到u后面,可以改变v窗口的元素
}
}
}
reverse(res.begin(), res.end());//正确的顺序
//for(auto it : res) cout << it << ' ';
if(res.size() < n - m + 1) cout << "No" << endl;
else cout << "Yes" << endl;
}
int main()
{
solve();
return 0;
}
E - Stamp的更多相关文章
- [BTS] Faulting application name: BTSNTSvc.exe, version: 3.9.469.0, time stamp: 0x4c547e09
Log Name: ApplicationSource: Application ErrorDate: 8/22/2013 1:28:35 AMEvent ID: 1000Task Category: ...
- AtCoder Grand Contest 002 D - Stamp Rally
Description We have an undirected graph with N vertices and M edges. The vertices are numbered 1 thr ...
- Can't parse message of type "gazebo.msgs.Packet" because it is missing required fields: stamp, type
在gazebo的仿真环境中,采用强化学习HER算法训练baxter执行reach.slide和pick and place任务. 运行HER算法,此时尚未启动gazebo仿真环境,出现如下报错: [l ...
- Stamp Rally
Stamp Rally 最大值最小,可以二分,然后并查集看能不能到z个点 但是询问过多,并且发现每次二分要加入的点并不是所有的m条边 于是就考虑整体二分 并查集的处理是重点: 对于一般的dfs分治树, ...
- make: *** No rule to make target `out/target/common/obj/APPS/framework-res_intermediates/src/R.stamp'
/********************************************************************************** * make: *** No r ...
- 编译出现No rule to make target `out/host/linux-x86/bin/aapt', needed by `out/target/common/obj/APPS/MyTv4_intermediates/src/R.stamp'问题
查找路径发现的确没有MyTv4_intermediates/src/R.stamp,这需要生成这个文件
- [AGC002D] Stamp Rally
确实有想到重构树,不过没有继续下去的思路. 可能是对重构树的性质不太懂. 这种题目我们可以二分答案,考虑怎么\(check\)呢,整体二分+并查集,建出重构树,找去第一个小于这个数的方点,查询他的子树 ...
- make[1]: *** [/workopenwrt/trunk/staging_dir/target-mipsel_24kec+dsp_uClibc-0.9.33.2/stamp/.tools_install_nnnnn] Error 2 make[1]: Leaving directory `/work/openwrt/trunk' make: *** [world]
主要原因是编译时未连上网,编译时需要下载些插件,连接网后,重启下系统再编译下.
- ROS time stamp and sync
1. https://answers.ros.org/question/189867/what-is-the-timestamp/ In ROS messages timestamp is taken ...
- [USACO18JAN]Stamp Painting
Description: Bessie想拿\(M\) 种颜色的长为\(K\) 的图章涂一个长为\(N\) 的迷之画布.假设他选择涂一段区间,则这段区间长度必须为\(K\) ,且涂完后该区间颜色全变成图 ...
随机推荐
- Linux - crontab 详解
linux 系统由(crond)这个系统服务来控制的,crond 是 linux 下用来周期性的执行某种任务或等待处理某些事件的一个守护进程,Linux 系统也提供了使用者控制计划任务的命令:cron ...
- VMware虚拟机上安装CentOS8详细教程
1.准备工作 1.1.需要准备好已安装完成的VMware虚拟机,如果您的电脑未安装VMware虚拟机,请参考以下连接:https://www.cnblogs.com/x1234567890/p/148 ...
- 使用电阻网络实现的vga驱动电路,fpga驱动vga显示器验证,代替gm7123芯片
之前驱动vga,要么是直接使用fpga管脚直接驱动,颜色为8原色 使用线缆 vs,hs,r,g,b一共五根线,三原色要么是0要么是1,所以色彩最多8种,rgb组合 若要实现真彩色驱动,如rgb888, ...
- SpringBoot集成WebServlet出现自定义单servlet请求失败的问题
一.导言 SpringBoot的真正核心是快速整合以及自动装配,所以在spring家族中springBoot不仅整合了Spring的IOC容器还兼容了WebServlet容器:这使得springBoo ...
- 出现TypeError: float() argument must be a string or a number, not _NoValueType(机器学习 Win11)
博客地址:https://www.cnblogs.com/zylyehuo/ 如果出现以下报错 则说明是torch.numpy等库的版本不匹配 可以去以下网站寻找匹配的版本 https://mirro ...
- C# - 获取枚举描述 - 使用增量源生成器
前言 C# 获取枚举描述的方法有很多, 常用的有通过 DescriptionAttribute 反射获取, 进阶的可以加上缓存机制, 减少反射的开销.今天我们还提供一种更加高效的方法,通过增量源生成器 ...
- 元模型:开启AI哲学思考的数字奇点
为推广动态模型让AI写的.动态模型和AI非常契合,元模型对AI有意义,所以让AI写更好.元模型其实是非常简单的一个模型,使用XML表示代码如下. <thing name="thing& ...
- SLAM导航全栈书的正确打开姿势
SLAM导航全栈书的正确打开姿势 随着人工智能.机器人.无人驾驶等技术的蓬勃发展,作为底层技术基石的SLAM也逐渐被大家所熟知.人工智能技术如果仅仅停留在虚拟的网络和数据之中的话,那么它挖掘并利用知识 ...
- 能详细地讲讲stm32该怎么学吗?
作为一个在嵌入式领域摸爬滚打了好几年的老兵,我想分享一下我学习STM32的心路历程和方法论.坦白说,刚开始接触STM32时,我也是一脸懵逼.机械专业毕业的我转行做嵌入式,第一份工作被调剂到电子部门,实 ...
- ShadowSql之精简版拆分
ShadowSql拆分为精简版和易用版,项目和nuget包同步拆分 ShadowSql项目拆分为ShadowSql.Core和ShadowSql Dapper.Shadow项目拆分为Dapper.Sh ...