zoukankan      html  css  js  c++  java
  • CF-552E-Two Teams

    pro:给出n, k和长度为n的数组a, 两个人轮流取数1先取,设a[i]是当前数组中最大值,则取走a[i - k]到a[i + k]这段数,然后把a[i + k + 1]和后面的补到 a[i - k]的位置。(当然要考虑前后边界,i - k不能小于1,i + k不能大于n)输出一个字符串s[i]表示a[i]属于1或2;

    sol:要解决的就是把a[i + k + 1]后面的往前移的操作,可以不用移,建两个数组,lft[i]表示i的上一个数下标,rgt[i]表示i下一个数的下标。

    • 有点像HDU1698用并查集解决的骚操作,都是标记上一个数或下一个数
      E - Two Teams GNU C++11 Accepted 46 ms 3300 KB
      #include "bits/stdc++.h"
      using namespace std;
      const int MAXN = 2e5 + 5;
      int a[MAXN], b[MAXN], lft[MAXN], rgt[MAXN];
      char ans[MAXN];
      int n, k, d = 1;
      void del(int t) {
          ans[t] = d ^ '0';
          lft[rgt[t]] = lft[t];
          rgt[lft[t]] = rgt[t];
      }
      int main() {
          scanf("%d%d", &n, &k);
          for (int i = 1; i <= n; i++) {
              scanf("%d", &a[i]);
              b[a[i]] = i;
              lft[i] = i - 1;
              rgt[i] = i + 1;
          }
          for (int i = n; i >= 1; i--) {
              int m = b[i];
              if (ans[m]) continue;
              del(m); 
              m = lft[m];
              for (int j = 0; j < k && m >= 1; j++) del(m), m = lft[m];
              m = rgt[m];
              for (int j = 0; j < k && m <= n; j++) del(m), m = rgt[m];
              d = 3 - d;
          }
          puts(ans + 1);
          return 0;
      }

      C++真好用,看到有人用STL里的东西来暴力,1900+ms卡过去了。本来想尝试hack一下的,数据太大无法提交。

  • 相关阅读:
    文件上传Web小案例
    加密方法(MD5加密)
    解决中文乱码(不可能解决不了)
    jquery的一些常见使用方法
    Ajax的作用
    日期时间格式的转换
    前端点击复制内容
    uniapp 移动端防止点击事件穿透
    getCurrentPages 获取当前网页完整的URL
    关闭微信浏览器网页
  • 原文地址:https://www.cnblogs.com/Angel-Demon/p/10726358.html
Copyright © 2011-2022 走看看