寒假思维训练计划day16 A. Did We Get Everything Covered?

今天更新一道1月27号晚上div2的C题作为素材,感觉用到了我的构造题总结模型,我总结了一系列的模型和例题。


摘要:

Part1 定义"边界贪心法"

Part2 题意

Part3 题解

Part4 代码

Part5 思维构造题 模型和例题


Part1 边界贪心法(该题所用到的模型):

边界贪心法: 对于整体而言,我们去除已经定好的情况,剩下难以确定的情况,我们从其最边缘的位置去考虑、去假设;一般要在问题的最边界处考虑,一般最边界决定总体的走向,后面会给例题以及其它的模型及其例题。


Part2 题意:Problem - A - Codeforces

题意:

给定,再给定一个长度为的字符串S,该字符串满足只包含前k个小写字母字符, 要求判断能否找到所有的长度为且字符组成只包含前个小写字母字符的字符串为S的子序列(删除一些元素后,其余元素顺序不变而组成的序列),能输出"YES",不能输出"NO",并构造出该字符串,它满足不是S的子序列。


Part3 题解:

题解:

1、已知:

2、我们不妨从头到尾遍历,当满足划分一个块,即块中元素恰好包含了所有的前个元素,当出现必然是最后一个块 ,因为它往后无法得到全部元素,一直到最后才能满足,否则就可以一直往后合并。

3、接下来,我么分好了块,假设有:表示分出的块,

我们进行分类讨论

3.1 当那我们必然能从每个块分别拿出任意字符,组成长度为n的子序列。

3.2 当,此时我们证明一定是无解的,

3.2.1 首先我们证明第一个命题,所有满足块的最后一个元素必然只存在一个在当前块中:当最后一个元素有两个,我们必然可以让块的右边界往左边移动,矛盾。

3.2.2 证明从前往后每次取块中最后一个元素的序列一定是唯一的:已知有, 其中满足的是:,当舍弃最后一个块的元素,我们知道该块中仅仅只有一个这样的元素(由3.2.1得), 只能在前面的块找到 ,显然也只由一个在块中,所以一直往前,必然无法找到新的可替代的,所以唯一。

3.2.3 所以取每个块的最后一个元素得到的,并且它是唯一的,我们只需要在后面补上任意元素,使得就一定不是S的子序列。


Part4 代码(C++)

C++代码(边界贪心法):

cpp 复制代码
#include <bits/stdc++.h>
#define int long long 
#define ff first 
#define ss second 
using namespace std; 
using PII = pair<int, int>; 
constexpr int N = 1e6 + 10;
constexpr int inf = 0x3f3f3f3f; 
int n, k, m; 
// int us[N][30], uss[N][30]; 
void solve() {
    cin >> n >> k >> m;
    string s; 
    cin >> s; 
    string ans = ""; 
    int o = 0; 
    for(int i = 0; i < m; i ++ ) {
        set<char> se; 
        se.insert(s[i]); 
        int j = i; 
        while(se.size() < k && j + 1 < m) {
            ++ j; 
            se.insert(s[j]); 
        }
        if(se.size() < k) {
            for(int j = 0; j < k; j ++ )
                if(se.count(('a' + j)) == 0) {
                    ans += ('a' + j); 
                    break; 
                }
        }
        else o ++, ans += s[j]; 
        
        i = j; 
    }
    if(o >= n) cout << "YES" << endl; 
    else {
        cout << "NO" << endl; 
        while(ans.size() < n) ans += 'a'; 
        cout << ans << endl;
    }
}
signed main() {
    ios::sync_with_stdio(false); 
    cin.tie(0); 
    cout.tie(0); 
    int ts; 
    cin >> ts; 
        
    while(ts -- ) solve(); 
    
    return 0;
}

Part5 思维构造题模型和例题

1、前后缀贪心 ,比如说观察前后缀的sum,去看以后怎么考虑最好。Problem - 1903C - Codeforces

2、双指针贪心法 ,考虑两端相消或者相互作用,还有就是考虑左右边界。 Problem - 1891C - Codeforces

Problem - 1907D - Codeforces

3、转换观察法 ,有些关系可以抽象成图,观察图的某些性质去总结规律。也可以抽象成一个集合,两个集合相等可以说明有解可构造。Problem - 1891C - Codeforces

4、打表找规律 ,一般没什么规律可循即可打表找规律,一般和数论有关的很喜欢考,acm也喜欢考,属于人类智慧题。Problem - 1916D - Codeforces

5、公式推导演算 ,常见的分为公式的等价变形、公式的化简 (这个常考,一般需要先证明某些性质,可以直接抵消,一般如果原公式处理起来很复杂时就可以考虑)。Problem - 1889B - Codeforces

6、考虑奇偶数去简化问题或者分类问题 ,从其中的一些运算性质入手,因为奇数偶数的加减以及**%运算(这个结论很重要)** 的结果的奇偶性是固定的,Problem - 1898C - Codeforces

7、根据性质构造模型 ,看看能不能分成几个块,几个不同的集合,再选择算法去解决。Problem - 1873G - Codeforces

8、考虑从小到大处理 ,或者是从大到小处理,有时候先处理小的对大的不会有影响,或者反过来,这样的处理顺序是最完美的。Problem - 1904D2 - Codeforces

9、边界贪心法 ,一般要在问题的最边界处考虑,有时候这样做结果是最优的,或者考虑边界上的影响,假如让影响最小,就使得影响<= 固定值 。 ​​​​​​Problem - E - Codeforces and Problem - 1903C - Codeforces
Problem - A - Codeforces

相关推荐
Dream it possible!3 分钟前
LeetCode 面试经典 150_图的广度优先搜索_最小基因变化(93_433_C++_中等)(广度优先搜索(BFS))
c++·leetcode·面试·广度优先
CoovallyAIHub44 分钟前
何必先OCR再LLM?视觉语言模型直接读图,让百页长文档信息不丢失
深度学习·算法·计算机视觉
CoovallyAIHub1 小时前
NAN-DETR:集中式噪声机制如何让检测更“团结”?
深度学习·算法·计算机视觉
CoovallyAIHub1 小时前
火箭工程大学多模态遥感检测新框架MROD-YOLO:如何将小目标检测精度提升至77.9%?
深度学习·算法·计算机视觉
steins_甲乙1 小时前
C++并发编程
开发语言·c++
CoovallyAIHub1 小时前
未来物体检测趋势:需要关注的 7 个关键问题
深度学习·算法·计算机视觉
业精于勤的牙1 小时前
小张刷题计划(二)
数据结构·算法
谈笑也风生1 小时前
期望个数统计(二)
算法
hans汉斯1 小时前
【人工智能与机器人研究】人工智能算法伦理风险的适应性治理研究——基于浙江实践与欧美经验的整合框架
大数据·人工智能·算法·机器人·数据安全·算法伦理·制度保障
CoderYanger1 小时前
动态规划算法-两个数组的dp(含字符串数组):42.不相交的线
java·算法·leetcode·动态规划·1024程序员节