Codeforces Round #345 (Div. 2)

Posted Running_Time

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 << ‘\n‘;

    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 << ‘\n‘;

    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\n", 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\n", ans);

    return 0;
}

E - Table Compression

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

分析:

 

以上是关于Codeforces Round #345 (Div. 2)的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces Round #345 (Div. 2)

Codeforces Round #345 (Div. 2)

A Joysticks (Codeforces Round 345 (Div 2) )

Codeforces Round #345 (Div. 2)C. Watchmen(想法题)

Codeforces Round #345 (Div. 1)B. Image Preview

Codeforces Round #345 Div.1 D.Zip-line 动态最长上升子序列