Codeforces Round #579 (Div. 3)

Codeforces Round #579 (Div. 3)

传送门

A. Circle of Students

这题我是直接把正序、逆序的两种放在数组里面直接判断。

Code

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 205;
int q, n;
int a[N], b[N], c[N];
int main() {
    ios::sync_with_stdio(false); cin.tie(0);
    cin >> q;
    while(q--) {
        cin >> n;
        for(int i = 1; i <= n; i++) cin >> a[i];
        int p;
        for(int i = 1; i <= n; i++) {
            if(a[i] == 1) {
                p = i; break;
            }
        }
        for(int i = p; i <= n; i++) {
            b[i - p + 1] = a[i];
        }
        for(int i = 1; i < p; i++) {
            b[i + n - p + 1] = a[i];
        }
        for(int i = p; i >= 1; i--) {
            c[p - i + 1] = a[i];
        }
        for(int i = n; i > p; i--) {
            c[n - i + p + 1] = a[i];
        }
        int ok = 1;
        for(int i = 1; i <= n; i++) {
            if(b[i] - b[i - 1] != 1) ok = 0;
        }
        if(ok) {
            cout << "YES" << '\n';
            continue;
        }
        ok = 1;
        for(int i = 1; i <= n; i++) {
            if(c[i] - c[i - 1] != 1) ok = 0;
        }
        if(ok) {
            cout << "YES" << '\n';
            continue;
        }
        cout << "NO" << '\n';
    }
    return 0;
}
B. Equal Rectangles

排序后判断即可,满足两个条件:对应边长相等;面积乘积相等。

Code

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1005;
int q, n;
int a[N], b[N];
int main() {
    ios::sync_with_stdio(false); cin.tie(0);
    cin >> q;
    while(q--) {
        cin >> n; n <<= 2;
        for(int i = 1; i <= n; i++) cin >> a[i];
        sort(a + 1, a + n + 1);
        int i = 1, j = n;
        int ok = 1;
        int ans = -1;
        while(i < j) {
            if(a[i] == a[i + 1] && a[j] == a[j - 1]) {
                if(ans == -1) {
                    ans = a[i] * a[j];
                } else {
                    if(ans != a[i] * a[j]) {
                        ok = 0; break;
                    }
                }
            } else {
                ok = 0; break;
            }
            i += 2; j -= 2;
        }
        if(ok) cout << "YES" << '\n';
        else cout << "NO" << '\n';
    }
    return 0;
}
C. Common Divisors

水题。

Code

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 4e5 + 5;
int q, n;
ll a[N];
int main() {
    ios::sync_with_stdio(false); cin.tie(0);
    cin >> n;
    for(int i = 1; i <= n; i++) cin >> a[i];
    ll g = a[1];
    for(int i = 2; i <= n; i++) {
        g = __gcd(g, a[i]);
    }
    int ans = 0;
    for(int i = 1; 1ll * i * i <= g; i++) {
        if(g % i == 0) {
            ans ++;
            if(g / i != i) ans++;
        }
    }
    cout << ans;
    return 0;
}
D2. Remove the Substring (hard version)

对于串\(t\)中的每个位置,求出其在串\(s\)中最早能出现的位置以及最晚能出现的位置。之后逐一枚举判断即可。

Code

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e5 + 5;
char s[N], t[N];
int f[N][26], g[N][26];
int nxt[26];
int h[N][2];
int main() {
    ios::sync_with_stdio(false); cin.tie(0);
    cin >> s + 1 >> t + 1;
    int n = strlen(s + 1), m = strlen(t + 1);
    for(int i = n; i >= 0; i--) {
        for(int j = 0; j < 26; j++) f[i][j] = nxt[j];
        nxt[s[i] - 'a'] = i;
    }
    for(int i = 0; i < 26; i++) nxt[i] = 0;
    for(int i = 1; i <= n + 1; i++) {
        for(int j = 0; j < 26; j++) g[i][j] = nxt[j];
        nxt[s[i] - 'a'] = i;
    }
    int now = 0;
    for(int i = 1; i <= m; i++) {
        h[i][0] = f[now][t[i] - 'a'];
        now = f[now][t[i] - 'a'];
    }
    now = n + 1;
    for(int i = m; i >= 1; i--) {
        h[i][1] = g[now][t[i] - 'a'];
        now = g[now][t[i] - 'a'];
    }
    int res = max(h[1][1] - 1, n - h[m][0]);
//    cout << h[1][1] << '\n';
    for(int i = 1; i < m; i++) {
        res = max(res, h[i + 1][1] - h[i][0] - 1);
    }
    cout << res;
    return 0;
}
E. Boxers

用个桶来进行标记就行,对于一个数,优先标记其前面的那一个数,其次标记本身,最后标记后面。
因为我们是从小到大枚举,可以证明这样最优。

Code

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 150005;
int q, n;
int a[N], c[N];
bool vis[N];
int main() {
    ios::sync_with_stdio(false); cin.tie(0);
    cin >> n;
    for(int i = 1; i <= n; i++) cin >> a[i];
    for(int i = 1; i <= n; i++) c[a[i]]++;
    if(c[1] > 1) {
        vis[1] = vis[2] = 1;
    } else if(c[1] == 1) vis[1] = 1;
    for(int i = 2; i < N; i++) {
        if(c[i]) {
            if(!vis[i - 1]) vis[i - 1] = 1;
            else if(!vis[i]) vis[i] = 1;
            else vis[i + 1] = 1;
            if(c[i] == 2) {
                if(!vis[i - 1] && i > 1) vis[i - 1] = 1;
                else if(!vis[i]) vis[i] = 1;
                else vis[i + 1] = 1;
            }
            if(c[i] >= 3) {
                vis[i] = 1;
                vis[i - 1] = 1;
                vis[i + 1] = 1;
            }
        }
    }
    int ans = 0;
    for(int i = 1; i < N; i++) ans += vis[i];
    cout << ans;
    return 0;
}
F1. Complete the Projects (easy version)

首先考虑把所有\(y>0\)的给搞完,然后对于\(y<0\)的,按照\(x+y\)从大到小排序,再逐一判断就行。
这里从大到小排序可以保证每次能够选得尽量地多,就相当于处理一个\(r->a_i+r\)的逆问题。

Code

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 60005;
int q, n, m, r;
struct node{
    int r, v;
}a[N], b[N];
bool vis[N];
int main() {
    ios::sync_with_stdio(false); cin.tie(0);
    cin >> n >> r;
    for(int i = 1; i <= n; i++) {
        cin >> a[i].r >> a[i].v;
    }
    while(1) {
        int mx = -N, id;
        for(int i = 1; i <= n; i++) {
            if(!vis[i] && a[i].r <= r && a[i].v > mx) {
                mx = a[i].v; id = i;
            }
        }
        if(mx < 0) break;
        vis[id] = 1;
        r += mx;
    }
    int tot = 0;
    for(int i = 1; i <= n; i++) {
        if(!vis[i]) b[++tot] = a[i];
    }
    sort(b + 1, b + tot + 1, [&](node a, node b){return a.r + a.v > b.r + b.v;});
    int ok = 1;
    for(int i = 1; i <= tot; i++) {
        if(r >= b[i].r && r + b[i].v >= 0) {
            r += b[i].v;
        } else ok = 0;
    }
    if(ok) cout << "YES" << '\n';
    else cout << "NO" << '\n';
    return 0;
}
F2. Complete the Projects (hard version)

类似于之前的思路,首先贪心地把\(y>0\)的部分尽量取完,然后对于\(y<0\)\(dp\)来处理。
\(dp[i][j]\)表示当前\(i\)个物品中选了若干个,\(r\)\(j\)时取的最大数量,转移时类似于背包。之后可以滚动数组优化一维。
注意一下我们还是要按照\(x+y\)来排序,否则有些状态不能转移到。

Code

#include <bits/stdc++.h>
#define MP make_pair
#define fi first
#define se second
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int N = 105, MAX = 60005;
int n, r;
pii a[N], b[N];
bool vis[N];
int dp[MAX];
int main() {
    ios::sync_with_stdio(false); cin.tie(0);
    cin >> n >> r;
    for(int i = 1; i <= n; i++) cin >> a[i].fi >> a[i].se;
    sort(a + 1, a + n + 1);
    int ans = 0;
    while(1) {
        int mx = -MAX, id = -1;
        for(int i = 1; i <= n; i++) {
            if(!vis[i] && a[i].fi <= r && a[i].se > mx) {
                mx = a[i].se; id = i;
            }
        }
        if(mx < 0) break;
        vis[id] = 1;
        r += mx; ans++;
    }
    int tot = 0;
    for(int i = 1; i <= n; i++) {
        if(a[i].fi <= r && a[i].se < 0) b[++tot] = a[i];
    }
    sort(b + 1, b + tot + 1, [&](pii a, pii b){
        return a.fi + a.se == b.fi + b.se ? a.fi > a.se : a.fi + a.se > b.fi + b.se;
    });
//    for(int i = 1; i <= tot; i++) cout << b[i].fi << ' ' << b[i].se << '\n';
    for(int i = 1; i <= tot; i++) {
        for(int j = b[i].fi; j <= r; j++) {
            if(j + b[i].se >= 0) dp[j + b[i].se] = max(dp[j + b[i].se], dp[j] + 1);
        }
    }
    int res = 0;
    for(int i = 0; i <= r; i++) res = max(res, dp[i]);
    ans += res;
    cout << ans;
    return 0;
}

转载于:https://www.cnblogs.com/heyuhhh/p/11356689.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值