zoukankan      html  css  js  c++  java
  • C. Glass Carving 正着做或者倒着做都可以

    http://codeforces.com/problemset/problem/527/C

    这题总体思路就是,每画一条线,然后就找到x间距的最max值和y间距的最max值,相乘就是当前的ans

    那么我需要维护这样的一个数列,每次往里面添加一个元素,然后查询相邻两个元素的差值的最大值。

    倒着做比较简单,首先把所有元素插上去,然后最大值直接暴力算一次。然后后来只有删除操作,这个操作只会让最大值变大。

    每次删除后,检查上面和下面的新间距,和最大值比较一下就好。

    #include <bits/stdc++.h>
    #define IOS ios::sync_with_stdio(false)
    using namespace std;
    #define inf (0x3f3f3f3f)
    typedef long long int LL;
    set<int> ss[2];
    LL ans[200000 + 20];
    struct Node {
        char op;
        int val;
    }node[200000 + 20];
    void fuck(int id) {
        if (node[id].op == 'H') {
            ss[1].erase(node[id].val);
        } else ss[0].erase(node[id].val);
    }
    void work() {
        int w, h, n;
        cin >> w >> h >> n;
        ss[0].insert(0); ss[0].insert(w);
        ss[1].insert(0); ss[1].insert(h);
        set<int> :: iterator it1, it2;
        for (int i = 1; i <= n; ++i) {
            char str[2];
            int val, flag = false;
            scanf("%s%d", str, &val);
            if (str[0] == 'H') {
                ss[1].insert(val);
            } else ss[0].insert(val);
            node[i].op = str[0];
            node[i].val = val;
        }
        int mx1 = 1;  // v
        it2 = ss[0].begin();
        it2++;
        for (it1 = ss[0].begin(); it2 != ss[0].end(); ++it2, ++it1) {
            mx1 = max(mx1, *it2 - *it1);
        }
        int mx2 = -inf;
        it2 = ss[1].begin();
        it2++;
        for (it1 = ss[1].begin(); it2 != ss[1].end(); ++it2, ++it1) {
            mx2 = max(mx2, *it2 - *it1);
        }
        ans[n] = 1LL * mx1 * mx2;
    //    cout << mx1 << " " << mx2 << endl;
        fuck(n);
        mx1 = 1;  // v
        it2 = ss[0].begin();
        it2++;
        for (it1 = ss[0].begin(); it2 != ss[0].end(); ++it2, ++it1) {
            mx1 = max(mx1, *it2 - *it1);
        }
        mx2 = 1;
        it2 = ss[1].begin();
        it2++;
        for (it1 = ss[1].begin(); it2 != ss[1].end(); ++it2, ++it1) {
            mx2 = max(mx2, *it2 - *it1);
        }
        for (int i = n - 1; i >= 1; --i) {
            if (node[i].op == 'H') {
                it1 = ss[1].lower_bound(node[i].val);
                it2 = it1;
                it2++;
                mx2 = max(mx2, *it2 - *it1);
                it2 = it1;
                it1--;
                mx2 = max(mx2, *it2 - *it1);
                it1++;
            } else {
                it1 = ss[0].lower_bound(node[i].val);
                it2 = it1;
                it2++;
                mx1 = max(mx1, *it2 - *it1);
                it2 = it1;
                it1--;
                mx1 = max(mx1, *it2 - *it1);
                it1++;
            }
            it2 = it1;
            it2++;
            it1--;
            fuck(i);
            ans[i] = 1LL * mx1 * mx2;
            if (node[i].op == 'H') {
                mx2 = max(mx2, *it2 - *it1);
            } else mx1 = max(mx1, *it2 - *it1);
        }
        for (int i = 1; i <= n; ++i) {
            cout << ans[i] << endl;
        }
    }
    
    int main() {
    #ifdef local
        freopen("data.txt", "r", stdin);
    //    freopen("data.txt", "w", stdout);
    #endif
        work();
        return 0;
    }
    View Code

    写的很乱,因为是绝杀的。

    正着也可以。

    用一个multiset来维护当前拥有的差值,一开始是h

    然后每添加一条边,可以找出在原数组中的上界和下界,这个差值是要删除的那个差值,然后添加新差值即可。

    #include <bits/stdc++.h>
    #define IOS ios::sync_with_stdio(false)
    using namespace std;
    #define inf (0x3f3f3f3f)
    typedef long long int LL;
    set<int> x, y;
    multiset<int> xx, yy;
    void work() {
        int w, h, n;
        cin >> w >> h >> n;
        x.insert(0), x.insert(w);
        y.insert(0), y.insert(h);
        xx.insert(w), yy.insert(h);
        for (int i = 1; i <= n; ++i) {
            char str[2];
            int pos;
            cin >> str >> pos;
            if (str[0] == 'H') {
                auto it1 = y.lower_bound(pos);
                int d1 = *it1;
                it1--;
                int d2 = *it1;
                auto del = yy.lower_bound(d1 - d2);
                yy.erase(del);
                yy.insert(d1 - pos);
                yy.insert(pos - d2);
                y.insert(pos);
            } else {
                auto it1 = x.lower_bound(pos);
                int d1 = *it1;
                it1--;
                int d2 = *it1;
                auto del = xx.lower_bound(d1 - d2);
                xx.erase(del);
                xx.insert(d1 - pos);
                xx.insert(pos - d2);
                x.insert(pos);
            }
            auto itx = xx.rbegin(), ity = yy.rbegin();
            cout << 1LL * (*itx) * (*ity) << endl;
        }
    }
    
    int main() {
    #ifdef local
        freopen("data.txt", "r", stdin);
    //    freopen("data.txt", "w", stdout);
    #endif
        IOS;
        work();
        return 0;
    }
    View Code
  • 相关阅读:
    Socket接口(基于 Linux-2.4.0已更新)
    IP协议源码分析(基于linux-2.4.0已更新)
    udp_sendmsg源码完整分析(基于linux5.12.13版本内核)
    UDP详细理解(实现部分基于linux5.12.12版本内核)
    IP地址分配(静态分配+动态分配+零配置)
    计算机网络由哪些硬件设备组成?(基础收录)
    浅析C语言定义时赋值、定义后赋值、定义时不赋值
    《C指针全解》让你不再害怕指针
    makdown文字图片居中字体颜色表格列宽
    (C语言内存二十一)C语言变量的存储类别和生存期
  • 原文地址:https://www.cnblogs.com/liuweimingcprogram/p/7222972.html
Copyright © 2011-2022 走看看