Codeforces Round #594 (Div. 2) 简要题解

http://codeforces.com/contest/1248

A. Integer Points

做法:

统计两条垂直线的截距的奇偶性就行了

#include "bits/stdc++.h"
 
using namespace std;
typedef long long ll;
const int maxn = 100000 + 10;
 
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int T, p, n;
    cin >> T;
    while (T--) {
        int odd = 0, eve = 0;
        cin >> n;
        for (int i = 1; i <= n; i++) {
            cin >> p;
            if (p & 1) odd++;
            else eve++;
        }
        cin >> n;
        ll ans = 0;
        for (int i = 1; i <= n; i++) {
            cin >> p;
            if (p & 1) ans += odd;
            else ans += eve;
        }
        cout << ans << endl;
    }
    return 0;
}

B. Grow The Tree

做法:排一个序,然后取前一半小的做一个方向的就可以了。

#include "bits/stdc++.h"
 
using namespace std;
typedef long long ll;
const int maxn = 100000 + 10;
int a[maxn], n, x;
//priority_queue<int, vector<int>, less<int> > qu;
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin >> n;
    ll l = 0, r = 0;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
        l += a[i];
    }
    sort(a + 1, a + n + 1);
    for (int i = 1; i <= n / 2; i++) {
        r += a[i];
    }
    l -= r;
    cout << l * l + r * r << endl;
    return 0;
}

C. Ivan the Fool and the Probability Theory

做法:我当时首先想到了只有一列的时候,我知道那个超级楼梯那道题,方案数就是斐波那契数列,因为有两种颜色因此要乘以2,然后,假设增加列数,然后我们通过观察发现也和斐波那契数列数列有关,猜一波结论,推几个样例没错。

#include "bits/stdc++.h"
 
using namespace std;
typedef long long ll;
const int maxn = 100000 + 10;
const ll mod = 1000000000 + 7;
int n, m;
ll f[maxn];
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin >> n >> m;
    f[0] = 1, f[1] = 1;
    for (int i = 2; i < maxn; i++) {
        f[i] = (f[i - 2] + f[i - 1]) % mod;
    }
    cout << 2 * (f[m] + f[n] - 1) % mod << endl;
    return 0;
}

D. The World Is Just a Programming Task

做法:简单版直接爆了枚举位置就可以了。

困难版,好像是关于括号的加减,然关于这个的一个折线图,要求循环序列一定是零最多的。所以扩展这个字符串到2n找到一个最少值开始,匹配括号,这里需要明白交换括号一定相邻的不同方向的括号,具体细节看看代码吧,建议查看官方题解,这道题应该是整个div2中最难的。

扫描二维码关注公众号,回复: 8587341 查看本文章
#include "bits/stdc++.h"
 
using namespace std;
typedef long long ll;
#define lson o<<1,l,mid
#define rson o<<1|1,mid+1,r
#define pii pair<int,int>
const int maxn = 300000 + 10;
const ll mod = 1000000000 + 7;
int n, m, now[maxn << 1], pre[maxn << 1];
char s[maxn << 1];
int sum[maxn << 1], sta[maxn << 1], lef[maxn << 1];
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin >> n >> (s + 1);
    for (int i = 1; i <= n; i++) s[i + n] = s[i];
 
    int cnt = 0, mn = 0, id = 0;
    for (int i = 1; i <= n; i++) {
        if (s[i] == '(') cnt++;
        else cnt--;
        if (cnt < mn) mn = cnt, id = i;
    }
    if (cnt != 0) {
        cout << "0\n1 1\n";
        return 0;
    }
    int top = 0, ans = 0;
    for (int i = id + 1; i <= id + n; i++) {
        if (s[i] == '(') sta[++top] = i;
        else {
            sum[i] = now[top];
            now[top] = 0;
            lef[i] = sta[top--];
            pre[i] = top;
            now[top]++;
        }
        if (top == 0) ans++;
    }
    int tmp = ans, x = 1, y = 1;
    for (int i = id + 2; i <= id + n; i++) {
        if (s[i] == ')') {
            if (pre[i] == 0 && sum[i] + 1 > ans) ans = sum[i] + 1, x = lef[i], y = i;
            if (pre[i] == 1 && sum[i] + tmp + 1 > ans) ans = sum[i] + tmp + 1, x = lef[i], y = i;
        }
    }
    cout << ans << endl;
    cout << (x - 1) % n + 1 << " " << (y - 1) % n + 1 << endl;
    return 0;
}

E. Queue in the Train

做法:抽象一下这个问题,假设一个队列,定义三个属性,a,b,c分别表示,a表示时间,b表示出入队列,c表示id

优先度也是按照abc,因此需要set或者堆进行维护。如果会一些技巧可以优化一维。

建议查看官方题解,讲得很好。

#include "bits/stdc++.h"
 
using namespace std;
typedef long long ll;
#define lson o<<1,l,mid
#define rson o<<1|1,mid+1,r
#define pii pair<int,int>
#define pll pair<ll,ll>
const int maxn = 100000 + 10;
const ll mod = 1000000000 + 7;
int n;
ll ans[maxn], p;
struct node {
    ll x, f, id;
    bool operator<(const node &a) const {
        if (x == a.x) {
            if (f == a.f) return id > a.id;
            return f > a.f;
        }
        return x > a.x;
    }
} a[maxn];
priority_queue<node> q1;
priority_queue<ll, vector<ll>, greater<ll> > q2;
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin >> n >> p;
    ll cnt = 0, count = 0;
    for (int i = 1; i <= n; i++) {
        cin >> a[i].x;
        a[i].id = i;
        a[i].f = 0;
        q1.push(a[i]);
    }
    ll tmp = n + 1;
    while (!q1.empty()) {
        node now = q1.top();
        q1.pop();
        cnt = max(cnt, now.x);
        if (now.f == 0) {
            now.f = 1;
            if (now.id < tmp) {
                tmp = now.id, count++;
                now.x = cnt + p;
                cnt = max(cnt, now.x);
                q1.push(now);
            } else {
                q2.push(now.id);
            }
        } else {
            ans[now.id] = now.x;
            count--;
            if (count == 0) {
                if (!q2.empty()) {
                    count++;
                    q1.push({cnt += p, 1, q2.top()});
                    tmp = q2.top();
                    q2.pop();
                }
//                else tmp = n + 1;
            }
        }
 
    }
    for (int i = 1; i <= n; i++)
        cout << ans[i] << " ";
    cout << endl;
    return 0;
}

F. Catowice City

做法:题我也没怎么读懂,然后觉得是一个强联通,然后看见很多人过了,然后。裸了一发tarjan过了。

#include "bits/stdc++.h"
 
using namespace std;
typedef long long ll;
#define lson o<<1,l,mid
#define rson o<<1|1,mid+1,r
#define pii pair<int,int>
#define pll pair<ll,ll>
const int maxn = 1000000 + 10;
const ll mod = 1000000000 + 7;
int n, m, colnum, cnt, dfsnum, top;
int vis[maxn], low[maxn], dfn[maxn];
int sta[maxn], col[maxn], dis[maxn];
vector<int> g[maxn];
void tarjan(int u) {
    low[u] = dfn[u] = ++dfsnum;
    sta[++top] = u;
    vis[u] = 1;
    for (auto v:g[u]) {
        if (!dfn[v]) {
            tarjan(v);
            low[u] = min(low[u], low[v]);
        } else {
            if (vis[v]) low[u] = min(low[u], low[v]);
        }
    }
    if (low[u] == dfn[u]) {
        vis[u] = 0;
        col[u] = ++colnum;
        while (sta[top] != u) {
            vis[sta[top]] = 0;
            col[sta[top--]] = colnum;
        }
        top--;
    }
}
void init(int n) {
    colnum = top = dfsnum = 0;
    for (int i = 0; i <= n; i++) {
        vis[i] = low[i] = dfn[i] = 0;
        sta[i] = col[i] = 0;
        g[i].clear();
    }
}
 
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int T, u, v;
    cin >> T;
    while (T--) {
        cin >> n >> m;
        init(n);
        for (int i = 1; i <= m; i++) {
            cin >> u >> v;
            if (u == v) continue;
            g[u].push_back(v);
//            g[v].push_back(u);
        }
        for (int i = 1; i <= n; i++) {
            if (!dfn[i]) tarjan(i);
        }
        if (colnum == 1) cout << "No" << endl;
        else {
            cout << "Yes" << endl;
            int cnt = 0;
            for (int i = 1; i <= n; i++) if (col[i] == 1) cnt++;
            cout << cnt << " " << n - cnt << endl;
            for (int i = 1; i <= n; i++) if (col[i] == 1) cout << i << " ";
            cout << endl;
            for (int i = 1; i <= n; i++) if (col[i] != 1) cout << i << " ";
            cout << endl;
        }
    }
    return 0;
}
发布了130 篇原创文章 · 获赞 80 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/KXL5180/article/details/102846230