Codeforces Gym 100513

来源:互联网 发布:丽得姿黑面膜淘宝 编辑:程序博客网 时间:2024/04/30 13:17

前面这些题都是一些模拟贪心= =描述还都很长。。。

100513I - Sale in GameStore

可以买任意一个游戏,然后可以选任意个加起来价值小于这个游戏的求最多能有几个。

#include <iostream>#include <algorithm>#include <cstdio>#include <cstring>#include <cmath>using namespace std;#define FIO ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);#define FILEREAD freopen("input.txt", "r", stdin);const int INF = 0x3f3f3f3f;const int N = 2001;const int MOD = 1e9 + 7;int main(){#ifndef ONLINE_JUDGE    FILEREAD#endif    FIO    int n;    cin >> n;    int p[N];    for (int i = 0; i < n; ++i)        cin >> p[i];    if (n == 1) {        cout << 1 << endl;        return 0;    }    sort(p, p + n);    int ans = 0, sum = 0;    for (int i = 0; i < n - 1; ++i) {        sum += p[i];        if (sum <= p[n - 1])            ans = i;        else            break;    }    cout << ans + 2 << endl;    return 0;}

100513F - Ilya Muromets

可以从序列中拿去长度为k的连续区间,然后再从新的序列中拿去长度为k的连续区间,求能拿走的最大和。DP[i][0/1/2]表示第i个前拿了j段的最大值。

#include <stdio.h>#include <string.h>#include <iostream>#include <algorithm>#include <vector>#include <queue>#include <stack>#include <set>#include <map>#include <string>#include <math.h>#include <stdlib.h>using namespace std;#define LL long long#define Lowbit(x) ((x)&(-x))#define lson l, mid, rt << 1#define rson mid + 1, r, rt << 1|1#define MP(a, b) make_pair(a, b)const int INF = 0x3f3f3f3f;const int MOD = 1000000007;const int maxn = 2e5 + 10;const double eps = 1e-8;const double PI = acos(-1.0);typedef pair<int, int> pii;int n, k;int a[maxn];int sum[maxn], dp[maxn][3];int main(){    //freopen("H:\\in.txt","r",stdin);    //freopen("H:\\out.txt","w",stdout);    scanf("%d%d", &n, &k);    for (int i = 1; i <= n; i++)        scanf("%d", &a[i]), sum[i] = sum[i-1] + a[i];    if (2 * k >= n)    {        printf("%d\n", sum[n]);        return 0;    }    int max1 = 0, max2 = 0;    dp[0][0] = dp[0][1] = dp[0][2] = 0;    for (int i = k; i <= n; i++)    {        dp[i][1] = max(dp[i-1][1], dp[i-k][0] + sum[i] - sum[i-k]);        dp[i][2] = max(dp[i-1][2], dp[i-k][1] + sum[i] - sum[i-k]);    }    int ans = dp[n][2];    //printf("%d\n", ans);    for (int i = 2 * k; i <= n; i++)        ans = max(ans, sum[i] - sum[i-2*k]);    printf("%d\n", ans);    return 0;

100513M - Variable Shadowing

一个变量如果已经定义过,在更深层的括号里面定义编译器会发出警告,给出代码输出警告信息。刚开始用stack做有点麻烦改用手动维护层数。

#include <stdio.h>#include <string.h>#include <iostream>#include <algorithm>#include <vector>#include <queue>#include <stack>#include <set>#include <map>#include <string>#include <math.h>#include <stdlib.h>using namespace std;#define LL long long#define Lowbit(x) ((x)&(-x))#define lson l, mid, rt << 1#define rson mid + 1, r, rt << 1|1#define MP(a, b) make_pair(a, b)const int INF = 0x3f3f3f3f;const int MOD = 1000000007;const int maxn = 2e5 + 10;const double eps = 1e-8;const double PI = acos(-1.0);typedef pair<int, int> pii;char s[55][55];int len[55];vector<pii> pos[30];map<pii, int> mp;void clear(int lv){    for (int i = 0; i < 26; i++)        while (pos[i].size() && mp[MP(pos[i][pos[i].size()-1].first, pos[i][pos[i].size()-1].second)] > lv)            pos[i].erase(pos[i].end()-1);}int main(){    //freopen("H:\\in.txt","r",stdin);    //freopen("H:\\out.txt","w",stdout);    int n;    scanf("%d", &n);    getchar();    for (int i = 1; i <= n; i++)        gets(s[i] + 1), len[i] = strlen(s[i] + 1);    int lv = 0;    for (int i = 1; i <= n; i++)        for (int j = 1; j <= len[i]; j++)            if (s[i][j] == '{')                lv++;            else if (s[i][j] == '}')            {                lv--;                clear(lv);            }            else if (s[i][j] == ' ') ;            else            {                //printf("%d %d %d\n", i, j, lv);                int num = s[i][j] - 'a';                if (pos[num].size())                {                    printf("%d:%d: warning: shadowed declaration of %c, the shadowed position is %d:%d\n", i, j, s[i][j], pos[num][pos[num].size()-1].first, pos[num][pos[num].size()-1].second);                }                pos[num].push_back(MP(i, j));                mp[MP(i, j)] = lv;            }    return 0;}

100513D - Data Center

能量超过所需的情况下尽量让低电压的服务器更少。
贪心模拟,被坑的一题

#include <iostream>#include <algorithm>#include <cstdio>#include <cstring>#include <cmath>#include <vector>using namespace std;#define FIO ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);#define FILEREAD freopen("input.txt", "r", stdin);const int INF = 0x3f3f3f3f;const int N = 200001;const int MOD = 1e9 + 7;struct server {    long long a;    int l, id;} s[N];vector<int> low, high;int main(){#ifndef ONLINE_JUDGE    FILEREAD#endif    FIO    int n;    long long m;    cin >> n >> m;    for (int i = 0; i < n; ++i) {        cin >> s[i].a >> s[i].l;        s[i].id = i + 1;    }    sort(s, s + n, [](server &x, server &y){return x.a > y.a;});    int r = 0;    long long sum = 0;    for (int i = 0; i < n; ++i) {        sum += s[i].a;        if (sum >= m) {            r = i + 1;            break;        }    }    long long sl = 0, sh = 0;    for (int i = 0; i < n; ++i)        if (s[i].l) {            low.push_back(i);            sl += s[i].a;        }        else            high.push_back(i);    int llast = low.size(), hlast = r - llast;    while (hlast < 0) {        sl -= s[low[--llast]].a;        ++hlast;    }    for (int i = 0; i < hlast; ++i)        sh += s[high[i]].a;    while (sl + sh < m) {        sl -= s[low[--llast]].a;        sh += s[high[hlast++]].a;    }    cout << r << ' ' << llast << endl;    for (int i = 0; i < llast; ++i)        cout << s[low[i]].id << ' ';    for (int i = 0; i < hlast; ++i)        cout << s[high[i]].id << ' ';    return 0;}

100513G - FacePalm Accounting

修改尽量少让序列的每个长度为K的区间的和都小于0,修改之后不能小于原数组的最小值。首先肯定尽量加在右边最好,然后暴力就行了。虽然最坏的时候他要跑k-1次才能减,但是均摊下来就可以了。

#include <stdio.h>#include <string.h>#include <iostream>#include <algorithm>#include <vector>#include <queue>#include <stack>#include <set>#include <map>#include <string>#include <math.h>#include <stdlib.h>using namespace std;#define LL long long#define Lowbit(x) ((x)&(-x))#define lson l, mid, rt << 1#define rson mid + 1, r, rt << 1|1#define MP(a, b) make_pair(a, b)const int INF = 0x3f3f3f3f;const int MOD = 1000000007;const int maxn = 2e5 + 10;const double eps = 1e-8;const double PI = acos(-1.0);typedef pair<int, int> pii;LL a[maxn];int main(){    //freopen("H:\\in.txt","r",stdin);    //freopen("H:\\out.txt","w",stdout);    int n, k;    LL mmin = INF;    scanf("%d%d", &n, &k);    for (int i = 1; i <= n; i++)        scanf("%lld", &a[i]), mmin = min(mmin, a[i]);    LL sum = 0, ans = 0;    for (int i = 1; i < k; i++)        sum += a[i];    for (int i = k; i <= n; i++)    {        sum += a[i];        sum -= a[i-k];        if (sum >= 0)        {            ans += sum + 1;            LL t = sum + 1;            int now = i;            while (t)            {                LL sub = min(t, a[now]-mmin);                a[now] -= sub;                t -= sub;                now--;            }            sum = -1;        }    }    printf("%lld\n", ans);    for (int i = 1; i <= n; i++)        printf("%lld ", a[i]);    puts("");    return 0;}

100513E - Election of a Mayor

所有选区有对面的得票和自己的得票,需要自己赢的选区超过总选区的一半才能胜利,可以合并相邻的两个选区,但是合并之后的选区不能再合并,求要合并多少个选区才能赢。
贪心的合并就行了,只要能增加一个获胜的选区或者减少一个失败的选区就可以合并,这样合并出来一定是最佳的,然后选出一些输出就行了。

#include <stdio.h>#include <string.h>#include <iostream>#include <algorithm>#include <vector>#include <queue>#include <stack>#include <set>#include <map>#include <string>#include <math.h>#include <stdlib.h>using namespace std;#define LL long long#define Lowbit(x) ((x)&(-x))#define lson l, mid, rt << 1#define rson mid + 1, r, rt << 1|1#define MP(a, b) make_pair(a, b)const int INF = 0x3f3f3f3f;const int MOD = 1000000007;const int maxn = 2e5 + 10;const double eps = 1e-8;const double PI = acos(-1.0);typedef pair<int, int> pii;int n;int m[maxn], r[maxn];int main(){    //freopen("H:\\in.txt","r",stdin);    //freopen("H:\\out.txt","w",stdout);    scanf("%d", &n);    int win = 0;    for (int i = 0; i < n; i++)    {        scanf("%d%d", &m[i], &r[i]);        if (m[i] > r[i]) win++;    }    vector<pii> ans;    for (int i = 1; i < n; i++)    {        int w = 0;        if (m[i] > r[i]) w++;        if (m[i-1] > r[i-1]) w++;        if (w == 1)        {            if (m[i] + m[i-1] > r[i] + r[i-1])            {                ans.push_back(MP(i-1, i));                i++;            }        }        if (w == 0)        {            ans.push_back(MP(i-1, i));            i++;        }    }    if (n - (2 * win - 1) > (int)ans.size())    {        puts("-1");        return 0;    }    else    {        printf("%d\n", max(0, n - (2 * win - 1)));        for (int i = 0; i < n - (2 * win - 1); i++)            printf("%d %d\n", ans[i].first + 1, ans[i].second + 1);    }    return 0;}
0 0
原创粉丝点击