Minieye杯第十五届华中科技大学程序设计邀请赛现场同步赛

https://ac.nowcoder.com/acm/contest/700#question

I
dp思想,维护以(i, j)为左上端点,长宽为k的矩形内最大值和最小值,dp[i][j] = min{dp[i][j], dp[i+1][j], dp[i][j+1], dp[i+1][j+1]}

#include <bits/stdc++.h>
using namespace std;
const int maxn = 500 + 5;
int a[maxn][maxn];
int minn[maxn][maxn], maxx[maxn][maxn];
int min_4(int a, int b, int c, int d) {
    return min(a, min(b, min(c, d)));
}
int max_4(int a, int b, int c, int d) {
    return max(a, max(b, max(c, d)));
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);

    int n, m, g;
    cin >> n >> m >> g;
    for(int i = 1; i <= n; ++i)
        for(int j = 1; j <= m; ++j)
            cin >> a[i][j], minn[i][j] = maxx[i][j] = a[i][j];

    int ans = 1;
    for(int k = 2; k <= min(n, m); ++k) {
        for(int i = 1; i <= n; ++i) if(i + k - 1 <= n) {
            for(int j = 1; j <= m; ++j) if(j + k - 1 <= m) {
                minn[i][j] = min_4(minn[i][j], minn[i + 1][j], minn[i][j + 1], minn[i + 1][j + 1]);
                maxx[i][j] = max_4(maxx[i][j], maxx[i + 1][j], maxx[i][j + 1], maxx[i + 1][j + 1]);
                if(maxx[i][j]- minn[i][j] <= g && ans < k) ans = k;
            }
        }
    }
    cout << ans << endl;
}

J
对于一个集合S,如果S中的数可以凑出mx,那么如果向集合S中新添加一个数x,若x<=mx+1,那么加入x后S可以凑出0~mx+x的所有数,但如果x>mx+1,则x对扩大可凑出的数的范围没有作用。
排序后按次序维护

 #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 4;
ll arr[maxn];
int main()
{
    int n;
    scanf("%d", &n);
    for(int i = 0; i < n; ++i) scanf("%lld", &arr[i]);
    ll mx = 0;
    sort(arr, arr + n);
    for(int i = 0; i < n; ++i) {
        if(arr[i] <= mx + 1) mx = max(mx, mx + arr[i]);
        else {
            printf("%lld\n", mx + 1);
            return 0;
        }
    }
    cout << mx + 1 << endl;
}

H
最短路,优先队列+pair优化代码

#include <bits/stdc++.h>
#define pi pair<int, int>
using namespace std;
const int maxn = 3e5 + 5;
const int inf = 0x3f3f3f3f;
map<string, int> id;
int n, tot, cnt[maxn];
vector<pair<pi, int>> E[maxn];
int getid(string s) {
    if(id.find(s) == id.end()) {
        id[s] = ++tot;
        int length = s.length(), vowel = 0;
        for(int i = 0; i < length; ++i) {
            if(s[i] == 'a' || s[i] == 'e' || s[i] == 'i' || s[i] == 'o' || s[i] == 'u')
                vowel++;
        }
        E[0].push_back(make_pair(pi(vowel, length), tot));
    }
    return id[s];
}
pi d[maxn];
priority_queue<pair<pi, int>, vector<pair<pi, int>>, greater<pair<pi, int>> >Q;
void Spfa() {
    for(int i = 0; i <= tot; ++i) d[i] = pi(inf, 0);
    d[0] = pi(0, 0);
    Q.push(make_pair(d[0], 0));
    while(!Q.empty()) {
        int u = Q.top().second; Q.pop();
        for(int i = 0; i < E[u].size(); ++i) {
            int v = E[u][i].second;
            if(pi(d[u].first + E[u][i].first.first, d[u].second + E[u][i].first.second) < d[v]) {
                d[v] = pi(d[u].first + E[u][i].first.first, d[u].second + E[u][i].first.second);
                Q.push(make_pair(d[v], v));
            }
        }
    }
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);

    cin >> n;
    string s1, s2;
    for(int i = 0; i < n; ++i) {
        cin >> s1;
        int node = getid(s1);
        cnt[node]++;
    }
    int m;
    cin >> m;
    for(int i = 0; i < m; ++i) {
        cin >> s1 >> s2;
        int u = getid(s1), v = getid(s2);
        E[v].push_back(make_pair(pi(0, 0), u));
    }
    Spfa();
    long long x = 0, y = 0;
    for(int i = 1; i <= tot; ++i) {
        x += 1ll * cnt[i] * d[i].first;
        y += 1ll * cnt[i] * d[i].second;
    }
    cout << x << " " << y << endl;
}

C
前缀和+树状数组维护

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e6 + 5;
int tre[maxn], m;
ll pre[maxn], mp[maxn];
void add(int x, int v) {
    while(x <= m) {
        tre[x] += v;
        x += (x & -x);
    }
}
int query(int x) {
    int sum = 0;
    while(x) {
        sum += tre[x];
        x -= (x & -x);
    }
    return sum;
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);

    int n, l, r;
    ll s;
    cin >> n >> l >> r >> s;
    for(int i = 1; i <= n; ++i) {
        cin >> pre[i];
        pre[i] += pre[i - 1];
        mp[i] = pre[i];
    }
    sort(mp + 1, mp + n + 1);
    m = unique(mp + 1, mp + n + 1) - mp - 1;
    for(int i = 1; i <= n; ++i) {
        pre[i] = lower_bound(mp + 1, mp + m + 1, pre[i]) - mp;
    }
    for(int i = l; i <= r; ++i)
        add(pre[i], 1);
    ll ans = 0;
    for(int i = 1; i <= n; ++i) {
        int pos = lower_bound(mp + 1, mp + m + 1, s + mp[pre[i - 1]]) - mp - 1;
        ans += query(m) - query(pos);
        add(pre[l++], -1);
        if(r < n) add(pre[++r], 1);
        if(l > n) break;
    }
    cout << ans << endl;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值