• 10月28日G、H、I题


    Train Problem I

    题意:给出元素入栈顺序和出栈顺序,问该入栈顺序的条件下是否可能得到该出栈顺序。

    分析:模拟。每次入栈后贪心匹配满足条件的出栈元素,最后判断栈是否为空。

    const int N = 1e5+10;
    char s1[N], s2[N];
    int ans[N];
    stack<char> st;
    void run() {
      int n;
      while (~scanf("%lld%s%s",&n,s1+1,s2+1)) {
        while (!st.empty()) st.pop();
        int i = 0, j = 1, cnt = 0;
        while (i++, i <= n) {
          st.push(s1[i]), ans[++cnt] = 1;
          while (!st.empty() && st.top() == s2[j]) st.pop(), j++, ans[++cnt] = 0;
        }
        if (!st.empty()) puts("No.");      
        else {
          puts("Yes.");
          rep(i,1,cnt) puts(ans[i] ? "in" : "out");
        }
        puts("FINISH");
      }
    }
    

    Feel Good

    题意:求max{子段和*该子段最小值}。

    分析:单调栈。单调栈求最大矩形面积模板的宽改为子段和来更新答案即可。

    const int N = 1e5+10;
    int a[N], sum[N], st[N];
    void run() {
      int n = rd(), tail = 1, ans = 0, l = 1, r = 1;
      rep(i,1,n) a[i] = rd(), sum[i] = sum[i-1] + a[i];
      rep(i,1,n) {
        bool flg = false;
        int tmp;
        while (tail > 1 && a[i] < a[st[tail-1]]) {
          flg = true;
          tmp = st[tail-1];
          if ((sum[i-1] - sum[st[tail-1]-1]) * a[st[tail-1]] > ans) {
            ans = (sum[i-1] - sum[st[tail-1]-1]) * a[st[tail-1]];
            r = i-1, l = st[tail-1];
          }
          tail--;
        }
        if (flg) {
          st[tail++] = tmp;
          a[tmp] = a[i];
        } else {
          st[tail++] = i;
        }
      }
      while (tail > 1) {
        if ((sum[n] - sum[st[tail-1]-1]) * a[st[tail-1]] > ans) {
            ans = (sum[n] - sum[st[tail-1]-1]) * a[st[tail-1]];
            r = n, l = st[tail-1];
          }
        tail--;
      }
      pnt(ans);
      put(l), pnt(r);
    }
    

    Vessels

    题意:\(n\)个船从上向下叠,第\(i\)个船容积\(a[i]\)

    2个操作:

    1.往下标\(p[i]\)的船注入\(x[i]\)的水,若已满则向下溢出。

    2.查询下标为\(k[i]\)的船里有多少水。

    分析:模拟。维护当前船往下还未注满水的第一艘船的下标。维护方法可以暴力优化或者并查集。

    const int N = 2e5+10;
    int c[N], a[N], fa[N];
    int find(int x) {return x ^ fa[x] ? fa[x] = find(fa[x]) : x;}
    void merge(int x, int y) {
      x = find(x), y = find(y);
      if (x != y) fa[x] = y;
    }
    void run() {
      int n = rd();
      rep(i,1,n) c[i] = rd();
      rep(i,1,n+1) fa[i] = i;
      int q = rd();
      while (q--) {
        if (rd() == 1) {
          int p = rd(), x = rd();
          while (x) {
            p = find(p);
            if (p > n) break;
            if (a[p] + x >= c[p]) {
              x -= c[p] - a[p];
              a[p] = c[p];
              merge(p, p+1);
            } else {
              a[p] += x;
              break;
            }
          }
        } else {
          int k = rd();
          pnt(a[k]);
        }
      }
    }
    
  • 相关阅读:
    80386寄存器
    删除 Windows 旧 OS 加载器
    [C#] Socket 通讯,一个简单的聊天窗口小程序
    [erl] erlang 进程注册和注销
    VB中 '&' 和 '+' 号的区别
    如何成为一个牛逼的程序员
    [VB] if 判断语句 和 If、IIf函数的比较
    C#中通过反射方法获取控件类型和名称
    薪资至少10K的一道题,你能拿下吗
    Jass 技能模型定义(—):半人马酋长的反击光环
  • 原文地址:https://www.cnblogs.com/KIMYON/p/13892234.html
Copyright © 2020-2023  润新知