codeforces 1187B 菜鸟题解

2 篇文章 0 订阅

codeforces 1187B 菜鸟题解

题目链接:https://codeforc.es/problemset/problem/1187/B

在这里插入图片描述

题目解释:

输入:n,长度为n的字符串, m,m次查询

给定一个字符串str,然后给m次查询,每次查询给一个字符串ask,判断ask的所有字符串在str字符串中出现的位置由前到后最大的。
说人话,
举个栗子:str = abcde, ask = abd,那么最后的结果就为4;
举个栗子:str = abacd, ask = aab,那么最后的结果就为3,因为有两个a,第二个a出现位置最远,所以就是3
最后一个栗子:str = abcade, ask = acae,最后结果就为6,最后一个e出现第六位。

题目捋清楚了,然后想一想题目给的条件,保证str和ask都为小写字母,小写字母总共26个,emm……

大概有点思路了

分析

因为在ask中出现多次同一个字符的话,要在str中找到相对应字符多次出现的位置,所以可以搞一个数组分别存储26个字母出现的位置,vector< int > v[26],这个数组用来存储每一个字母出现的位置,不是下标。

这个问题解决了

第二个问题,查询呢,也就是所有字母里面下标的从头到尾出现次序的最大值,

还是str = abcade, ask = acae,
那么vector[‘a’ - ‘a’] = {1, 4}, vector[‘c’ - ‘a’] = {3}, vector[‘e’ - ‘a’] = 6

用ans来记录答案,遍历ask数组

1.a ans = max(ans, vector[‘a’][0]) = 1
2.c ans = max(ans, vector[‘c’][0]) = 3
3.a ans = max(ans, vector[‘a’][1]) = 4
4.e ans = max(ans, vector[‘e’][0]) = 6

通过上面的手动计算,也就明了了

我们除了需要一个vector来记录每个字母出现的下标,还要记录当前这个字母遍历了几次,也就是当前字母在vector中遍历到哪个下标了

所以新建一个ind[26]的数组,初始化为0,在上面的例子中,ind的变化情况:

1.变换前:ind[‘a’] = 0,变化后: index[‘a’] = 1, ans = 1
2.变换前:ind[‘c’] = 0,变化后: index[‘c’] = 1, ans = 3
3.变换前:ind[‘a’] = 1,变化后: index[‘a’] = 2, ans = 4
4.变换前:ind[‘e’] = 0,变化后: index[‘e’] = 1, ans = 6

到这里思路明确了,代码也就出来了

上代码

AC代码:

#include <bits/stdc++.h>
using namespace std;

const int N = 26;
vector<int> v[N];

int main(){
    ios::sync_with_stdio(false);
    int n, m;
    string str;
    cin >> n >> str;
    for (int i = 0; i < n; i++) v[str[i] - 'a'].push_back(i + 1);
    cin >> m;
    while (m--){
        int ind[N] = {0};
        string ask;
        cin >> ask;
        int ans = 0;
        for (int i = 0; i < ask.length(); i++){
            ans = max(ans, v[ask[i] - 'a'][ind[ask[i] - 'a']++]);
        }
        cout << ans << endl;
    }
    return 0;
}

我第一次,为什么想要用set做,脑瘫菜鸟的日常,难受QAQ

有志者,事竟成,破釜沉舟,百二秦关终属楚。
苦心人,天不负,卧薪尝胆,三千越甲可吞吴。

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值