• Educational Codeforces Round 151 (Rated for Div. 2)


    A. Forbidden Integer

    贪心的分情况讨论:x没被禁,全1,x被禁,分情况讨论:

    如果k<=1,无解。 k=2时奇数,无解。 k>2时,有解。

    1. void solve(){
    2. int n, k, x; cin >> n >> k >> x;
    3. if (x != 1){
    4. vi a(n, 1);print(yes); print(len(a));print(a);return;
    5. }
    6. else{
    7. if (k <= 1) {print(no); return;}
    8. else if (k == 2 && n & 1){print(no); return;}
    9. else { print(yes);
    10. vi a;
    11. while (n > 3) {a.pb(2); n-= 2;}
    12. a.pb(n == 2 ? 2 : 3);
    13. print(len(a));
    14. print(a);
    15. }
    16. }
    17. }

    B. Come Together

    二维空间中三个点ABC,求BC到A的最短路径中的最长公共距离。问题等价于:求A到BC的路径中最长公共距离。

    当B和C有公共距离时,A一定是满足这个条件:A在BC上或者下方,A在BC左或者右方,直接计算即可。

    1. void solve(){
    2. ll dis = 0;
    3. pi a, b, c; cin >> a.first >> a.second >> b.first >> b.second >>c.first >>c.second;
    4. if (a.first >= max(b.first, c.first)) {dis += a.first - max(b.first, c.first);}
    5. else if (a.first <= min(b.first, c.first)) {dis += min(b.first, c.first) - a.first;}
    6. //print(dis);
    7. if (a.second >= max(b.second, c.second)) {dis += a.second - max(b.second, c.second); }
    8. else if (a.second <= min(b.second, c.second)) {dis += min(b.second, c.second) - a.second;}
    9. print(dis + 1);
    10. }

    最后dis+1是考虑了在a点汇合时的一个公共坐标

    C. Strong Password

    枚举字符串的时间复杂度是O(n * pow(m, 10)),必TLE。

    于是问题转换为构造S中不出现的子串。

    答案字符串的长度为m,对于0~m-1位置的字符,贪心地枚举每个位置上的字符的最远匹配距离。这个策略可以证明一定是最优解。

    1. void solve(){
    2. string s; cin >> s;
    3. int m; cin >> m;
    4. string t1, t2;cin >>t1 >> t2;
    5. int rb = 0;
    6. lfor (i, 0, m - 1){
    7. int r = 0;
    8. if(t1[i] > t2[i]) swap(t1[i], t2[i]);
    9. while (t1[i] <= t2[i]){
    10. int t = s.find(t1[i], rb);
    11. if(t==-1){print(yes); return;}
    12. t ++;
    13. r = max(r, t);
    14. t1[i] ++;
    15. }
    16. rb = max(rb, r);
    17. }
    18. print(no);
    19. }

    D. Rating System

    在数组求前缀和的过程中找到一个k值,当前缀和在做减法运算时,可以让前缀和不低于k。求前缀和最大的情况下的k值。

    贪心策略:可以发现为了让最终前缀和最大,需要消除掉在计算过程中对前缀和影响最大的负数。于是问题转化为,贪心查找数组中连续区间的最小值(值是负数),然后记录这个区间前面的前缀和,就是答案。

    1. void solve(){
    2. int n; cin >> n;
    3. vi a(n); liter(x, a) cin >> x;
    4. ll minn = 2e9;
    5. ll curmin = 0;
    6. ll sum = 0;
    7. ll ans = 0;
    8. ll presum = 0;
    9. lfor (i, 0, n - 1){
    10. curmin += a[i];
    11. if (cmin(minn, curmin)){ //全局最小值小于当前局部连续区间最小值
    12. ans = presum;
    13. }
    14. sum += a[i];
    15. if (cmin(curmin, 0ll)){ //当前局部连续区间最小值大于0,舍弃之前的区间,并记录当前的前缀和
    16. presum = sum;
    17. }
    18. }
    19. print(ans);
    20. }

  • 相关阅读:
    Redis 命令
    【golang】go app 优雅关机 Graceful Shutdown How?
    Ubuntu环境下以编译源码的方式安装Vim
    使用注解新开事务 @Transactional
    一文搞定Vue2组件通信
    【双指针】移动零
    pnpm v9 正式发布,已停止 Node.js v16 支持
    【常见SQL报错及解决办法】个人记录,自用
    基于jeecgboot的flowable流程支持online表单(二)
    EF Core报错:Error Number:-2146893019
  • 原文地址:https://blog.csdn.net/m0_73965117/article/details/132717150