zoukankan      html  css  js  c++  java
  • Codeforces Round #345 (Div. 2)

    DFS A - Joysticks

    嫌麻烦直接DFS暴搜吧,有坑点是当前电量<=1就不能再掉电,直接结束。

    #include <bits/stdc++.h>
    
    typedef long long ll;
    const int N = 1e5 + 5;
    int ans = 0;
    
    void DFS(int a, int b, int step) {
        if (a <= 0 || b <= 0) {
            ans = std::max (ans, step); return ;
        }
        if (a < b && b - 2 >= 0) {
            DFS (a + 1, b - 2, step + 1);
        } else if (a >= b && a - 2 >= 0) {
            DFS (a - 2, b + 1, step + 1);
        }
    }
    
    int main() {
        int a, b;   std::cin >> a >> b;
        ans = 0;
        DFS (a, b, 0);
        std::cout << ans << '
    ';
    
        return 0;
    }

    构造 + 贪心 B - Beautiful Paintings

    每次取出不重复的递增序列,直到集合为空

    #include <bits/stdc++.h>
    
    typedef long long ll;
    const int N = 1e5 + 5;
    std::vector<int> vec;
    
    int main() {
        int n;  std::cin >> n;
        for (int x, i=0; i<n; ++i) {
            std::cin >> x; vec.push_back (x);
        }
        std::sort (vec.begin (), vec.end ());
        int ans = 0;
        while (vec.size () > 0) {
            std::vector<int> tmp;
            int pre = 0, num = 0;
            for (auto x: vec) {
                if (x > pre) {
                    num++; pre = x;
                } else {
                    tmp.push_back (x);
                }
            }
            ans += num - 1; vec = tmp;
        }
        std::cout << ans << '
    ';
    
        return 0;
    }

    数学 + 容斥 C - Watchmen

    化简公式得到找到pair (i, j) xi == xj || yi == yj。找两次再容斥一下。map做更好。

    #include <bits/stdc++.h>
    
    typedef long long ll;
    const int N = 2e5 + 5;
    const int INF = 1e9 + 7;
    std::pair<int, int> point[N];
    
    ll calc(int n) {
        return 1ll * n * (n - 1) / 2;
    }
    
    bool cmpx(std::pair<int, int> a, std::pair<int, int> b) {
        return a.first < b.first;
    }
    
    bool cmpy(std::pair<int, int> a, std::pair<int, int> b) {
        return a.second < b.second;
    }
    int main() {
        int n; scanf ("%d", &n);
        for (int x, y, i=0; i<n; ++i) {
            scanf ("%d%d", &x, &y);
            point[i] = std::make_pair (x, y);
        }
        std::sort (point, point+n, cmpx);
        ll ans = 0;
        int x = INF, y = INF, num = 1;
        for (int i=0; i<n; ++i) {
            if (x == point[i].first) {
                num++;
            } else {
                x = point[i].first;
                if (num > 1) {
                    ans += calc (num);
                }
                num = 1;
            }
        }
        if (num > 1) {
            ans += calc (num);
        }
        std::sort (point, point+n, cmpy);
        x = INF; y = INF; num = 1;
        for (int i=0; i<n; ++i) {
            if (y == point[i].second) {
                num++;
            } else {
                y = point[i].second;
                if (num > 1) {
                    ans += calc (num);
                }
                num = 1;
            }
        }
        if (num > 1) {
            ans += calc (num);
        }
        std::sort (point, point+n);
        x = INF; y = INF; num = 1;
        for (int i=0; i<n; ++i) {
            if (x == point[i].first && y == point[i].second) {
                num++;
            } else {
                x = point[i].first, y = point[i].second;
                if (num > 1) {
                    ans -= calc (num);
                }
                num = 1;
            }
        }
        if (num > 1) {
            ans -= calc (num);
        }
        printf ("%I64d
    ", ans);
    
        return 0;
    }

    two points D - Image Preview

    题意:浏览图片,浏览,滑动以及反转需要时间,问在T时间内最多浏览多少图片。

    分析:定义两个指针from,to,可行的方案是n+1->from,from->n+1,n+1->to或者n+1->to,to->n+1,n+1->from,还有from->to。前两个重复滑动的可以选择距离小的,第三个只要定义to=n+1就对了。其实可以用二分做的。

    #include <bits/stdc++.h>
    
    typedef long long ll;
    const int N = 5e5 + 5;
    char str[2*N];
    ll tim[2*N];
    int n, a, b, T;
    
    ll get_time(int from, int to) {
        ll ret = tim[from] - tim[to-1];
        int move = from - to + std::min (from-(n+1), (n+1)-to);
        return ret + 1ll * a * move;
    }
    
    int main() {
        scanf ("%d%d%d%d", &n, &a, &b, &T);
        scanf ("%s", str + 1);
        for (int i=1; i<=n; ++i) {
            tim[i] = (str[i] == 'w' ? (b+1) : 1);
        }
        for (int i=n+1; i<=2*n; ++i) {
            tim[i] = tim[i-n];
        }
        for (int i=1; i<=2*n; ++i) {
            tim[i] += tim[i-1];
        }
        int ans = 0;
        int from = n + 1;
        for (int to=2; to<=n+1; ++to) {
            while (from < to+n-1 && get_time (from+1, to) <= T) from++;
            if (get_time (from, to) <= T) ans = std::max (ans, from - to + 1);
        }
        printf ("%d
    ", ans);
    
        return 0;
    }

    图论 + 并查集 E - Table Compression

    题意:给一个矩阵,求新的矩阵,使得原矩阵的同行,同列的大小关系不变,且使得新矩阵的最大值最小。即离散化

    分析:找好顺序,一个一个从小到大填充就行了。因为有相同数字的存在,使用并查集使得将相同的数字赋值离散化后相同的数字。因为有行和列共同影响一个数字,所以建立一个大数到小数的图,类似树形DP,选择当前行或列的最大值+1为离散化后的数字

    #include <bits/stdc++.h>
    
    const int N = 1e6 + 5;
    std::pair<int, std::pair<int, int> > A[N];
    int val[N], ans[N];
    int mr[N], mc[N];
    int rt[N];
    std::vector<int> edge[N];
    std::vector<int> num[N];
    
    int Find(int x) {
        return rt[x] == x ? x : rt[x] = Find (rt[x]);
    }
    
    int main() {
        int n, m; scanf ("%d%d", &n, &m);
        int tot = n * m;
        for (int i=0; i<n; ++i) {
            for (int j=0; j<m; ++j) {
                scanf ("%d", &val[i*m+j]);
                A[i*m+j].first = val[i*m+j];
                A[i*m+j].second = std::make_pair (i, j);
                rt[i*m+j] = i * m + j;
            }
        }
        std::fill (mr, mr+n, -1);
        std::fill (mc, mc+m, -1);
        std::sort (A, A+tot);
        for (int i=0; i<tot; ++i) {
            int r = A[i].second.first, c = A[i].second.second;
            int pos = r * m + c;
            if (mr[r] != -1) {
                if (val[mr[r]] == A[i].first) {
                    rt[pos] = Find (mr[r]);
                } else {
                    edge[pos].push_back (mr[r]);
                }
            }
            if (mc[c] != -1) {
                if (val[mc[c]] == A[i].first) {
                    rt[Find (pos)] = Find (mc[c]);
                } else {
                    edge[pos].push_back (mc[c]);
                }
            }
            mr[r] = mc[c] = pos;
        }
        for (int i=0; i<tot; ++i) {
            num[Find (i)].push_back (i);
        }
        for (int i=0; i<tot; ++i) {
            int r = A[i].second.first, c = A[i].second.second;
            int id = r * m + c;
            if (Find (id) == id) {
                int _max = 0;
                for (auto u: num[id]) {
                    for (auto v: edge[u]) {
                        _max = std::max (_max, ans[v]);
                    }
                }
                for (auto u: num[id]) {
                    ans[u] = _max + 1;
                }
            }
        }
        for (int i=0; i<n; ++i) {
            for (int j=0; j<m; ++j) {
                printf ("%d ", ans[i*m+j]);
            }
            puts ("");
        }
    
        return 0;
    }
    

      

    编译人生,运行世界!
  • 相关阅读:
    任务框架--Quartz 配置文件
    地址和值
    线性基学习笔记
    S07
    如何在实际项目中使用PageHelper分页插件
    设计模式:原型模式
    常用JS代码片段
    Thomson Plaza里面的三家店以及水果大会
    13.搜索过滤
    07-多线程
  • 原文地址:https://www.cnblogs.com/Running-Time/p/5258127.html
Copyright © 2011-2022 走看看