Codeforces Round #811 (Div. 3)D.Color with Occurrences

题意:给定一个字符串 t ,然后再给出一系列字符串 a ,对于 t 中子串于 a 相同的可以染上颜色,问把 t 全部染上颜色至少用几次

        因为字串和源字符串数据量都很小,所以只用暴力在 t 中找出所有的对应覆盖区间,然后做一遍区间覆盖贪心即可。当时场上很快就想到了做法,但是写代码bebug能力太差了,改了两个小时都没改出来

#include<bits/stdc++.h>
#define debug1(a) cout<<#a<<'='<< a << endl;
#define debug2(a,b) cout<<#a<<" = "<<a<<"  "<<#b<<" = "<<b<<endl;
#define debug3(a,b,c) cout<<#a<<" = "<<a<<"  "<<#b<<" = "<<b<<"  "<<#c<<" = "<<c<<endl;
#define debug4(a,b,c,d) cout<<#a<<" = "<<a<<"  "<<#b<<" = "<<b<<"  "<<#c<<" = "<<c<<"  "<<#d<<" = "<<d<<endl;
#define debug5(a,b,c,d,e) cout<<#a<<" = "<<a<<"  "<<#b<<" = "<<b<<"  "<<#c<<" = "<<c<<"  "<<#d<<" = "<<d<<"  "<<#e<<" = "<<e<<endl;
#define debug0(x) cout << "debug0: " << x << endl
#define fr(t, i, n) for (int i = t; i < n; i++)
#define fi first
#define se second
using namespace std;

typedef long long LL;
typedef pair<int,int> PII;
typedef pair<LL,LL> PLL;

struct PIIi{
    int fi,se;
    int id;
    bool operator ==(const PIIi&a)const{
        return fi == a.fi && se == a.se && id == a.id;
    }
};
bool st[1000];
vector<PIIi> edge;
void solve(){
	string t;cin >> t;
    int n;cin >> n;
    string kmp;
    edge.clear();
    fr(0,i,n){
        cin >> kmp;
        int m = kmp.size();
        for(int j = 0;j <= t.size();j ++){
            if(t.substr(j,m) == kmp)
            {
                edge.emplace_back(PIIi{j,j+m,i});//末尾多的也行
                //debug2(j,j+m);
            }
        }
    }
    sort(edge.begin(),edge.end(),[](PIIi a,PIIi b){
        return a.fi < b.fi || a.fi == b.fi && a.se > b.se;
    });

    //edge.erase(unique(edge.begin(),edge.end()),edge.end());
    /*memset(st,0,sizeof st);//判断有无解
    for(int i = 0;i < edge.size();i ++)
    {
        for(int j = edge[i].fi;j < edge[i].se;j ++)st[j] = true;
    }
    for(int i = 0;i <= n;i ++)if(!st[i])
    {
        cout << -1 << endl;
        return ;
    }
    */
    int start = 0,idx = 0,ed = t.size();
    bool cover = 0;
    vector<PII> ans;
    for(int i = 0;i < edge.size();)
    {
        int j = i,r = -1e9,idk = 0;
        while(j < edge.size() && edge[j].fi <= start)
        {
            if(edge[j].se > r)
            {
                r = edge[j].se;
                idx = edge[j].id;
                idk = edge[j].fi;
            }
            j ++;
        }
        
        if(r < start)break;

        ans.emplace_back(PII{idx,idk});
        start = r;
        i = j;
        if(r == t.size())
        {
            cover = 1;
            break;
        }
    }
    //ans.push_back(PII{idx,cl}),step++;
    if(!cover)
    {
        cout << -1 << endl;
        return;
    }
    cout << ans.size() << endl;
    for(auto x:ans)cout << x.fi+1 << " " << x.se+1 << endl;
    
}   
 
int main()
{
    
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    
    int T = 1;cin >> T;
    while(T--){
        solve();
    }
    return 0;
}

 区间覆盖的模板是在已覆盖区间内找伸出外面最长的,同时注意处理边界

因为这个题目的数据量很小,所以一开始我就想先把所有区间能覆盖的进行判断,如果还有未覆盖成功的区间就不用贪心这个步骤了,可以减少代码量和思维量。

但是显然判断全区间是否被覆盖写错了,把 t 的长度用成了 n ,导致mle

这个故事告诉我们,代码变量名不要瞎起orz

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值