Codeforces Round #419 (Div. 2)

A题

题意:
给定一个时间,求下一个特定时间之前要睡的时间(回文串)

顺序模拟下就可

#include <bits/stdc++.h>
using namespace std;

char s[6];
int d[4];

void tran(char *s){
    if(++s[3] > '9'){
        s[3] = '0';
        if(++s[2] > '5'){
            s[2] = '0';
            ++s[1];
            if(s[0] == '2' && s[1] == '4'){
                s[0] = s[1] = '0';
            }
            if(s[1] > '9'){
                s[1] = '0';
                ++s[0];
            }
        }
    }
}
bool test(char *s){
    return s[0] == s[3] && s[1] == s[2];
}
int main()
{
   // freopen("ce.in", "r", stdin);
    cin >> s;
    s[2] = s[3];
    s[3] = s[4];
    s[4] = 0;
    int ans = 0;
    while(!test(s)) ++ans, tran(s);
    cout << ans << endl;
    return 0;
}

B题

[x, y]染色, 差分数组:
++d[x], –d[y + 1];
d[i] = a[i] - [i - 1];
a[0] = 0;

所以 a[i]=ii=1d[i]
前缀和:
令sum[i]为[1, n]中满足的个数
sum[i]=ni=1(a[i]>=k)?1:0

则对于查询[x, y],
ans = sump[y] - sum[x - 1]

当时用线段树做的..

#include <bits/stdc++.h>
using namespace std;

const int N = 200010;

int a[200010];

int main()
{
    //freopen("ce.in", "r", stdin);
    memset(a, 0, sizeof a);
    int n, k, q, l, r;
    cin >> n >> k >> q;
    while(n--){
        cin >> l >> r;
        ++a[l], --a[r + 1];
    }
    for(int i = 1; i < 200001; ++i) a[i] += a[i - 1];
    for(int i = 1; i < 200001; ++i) {
            a[i] = a[i] >= k ? 1:0;
            a[i] += a[i - 1];
    }
    while(q--){
        cin >> l >> r;
        cout << a[r] - a[l - 1] << endl;
    }
    return 0;
}

C题

1首先比较行数, 列数;
较大的优先删;

2存每一行/列的multiset
3取第一行/列的最大最小, 如果两值相等, 则判断每一行/列是不是都相同,
如果相同按数目删行/列, 不同无解;
第一行/列两值不相等, 找最大的书局那列/行删, 记下列/行号;
重复3直至两值相等

code:

#include <bits/stdc++.h>
using namespace std;
int n;
int g[110][110];
int ansr[110];
multiset<int> s[110];
map<int, set<int> >mp;
multiset<int> ansl;

int main()
{
    //freopen("ce.in", "r", stdin);

    int r, c;
    scanf("%d%d", &r, &c);
    for(int i = 1; i <= r; ++i)
        for(int j = 1; j <= c; ++j)
        {
            scanf("%d", &g[i][j]);
            //   printf("%d\n", g[i][j]);
        }
    if(r >= c)
    {
        for(int i = 1; i <= c; ++i)
            for(int j = 1; j <= r; ++j)
            {
                s[i].insert(g[j][i]);
            }
        for(int i = 1; i <= r; ++i) mp[g[i][1]].insert(i);
        multiset<int>::iterator op, ed;
        set<int>::iterator it;
        op = s[1].begin();
        ed = --s[1].end();
        int sum = 0;
        while(*op < *ed)
        {
            //     printf("%d %d\n", *op, *ed);

            int v = *ed;
            it = --mp[v].end();
            int row = *it;
            ansl.insert(row);
            for(int i = 1; i <= c; ++i)
            {
                s[i].erase(--s[i].end());
                s[i].insert(g[row][i] - 1);
                if(--g[row][i] < 0)
                {
                    printf("-1\n");
                    return 0;
                }
            }
            mp[v].erase(row);
            mp[v - 1].insert(row);
            ++sum;
            op = s[1].begin();
            ed = --s[1].end();
            //  printf("%d %d\n", *op, *ed);
        }
        for(int i = 1; i <= c; ++i)
        {
            op = s[i].begin();
            ed = --s[i].end();
            if(*op < *ed)
            {
                printf("-1\n");
                return 0;
            }
            ansr[i] = *op;
            sum += ansr[i];
        }

        printf("%d\n", sum);
        for(op = ansl.begin(); op != ansl.end(); ++op)
            printf("row %d\n", *op);
        for(int i = 1; i <= c; ++i)
        {
            for(int j = 1; j <= ansr[i]; ++j)
            {
                printf("col %d\n", i);
            }
        }
    }else{
        for(int i = 1; i <= r; ++i)
            for(int j = 1; j <= c; ++j)
            {
                s[i].insert(g[i][j]);
            }
        for(int i = 1; i <= c; ++i) mp[g[1][i]].insert(i);
        multiset<int>::iterator op, ed;
        set<int>::iterator it;
        op = s[1].begin();
        ed = --s[1].end();
        int sum = 0;
        while(*op < *ed)
        {
            //     printf("%d %d\n", *op, *ed);

            int v = *ed;
            it = --mp[v].end();
            int col = *it;
            ansl.insert(col);
            for(int i = 1; i <= r; ++i)
            {
                s[i].erase(--s[i].end());
                s[i].insert(g[i][col] - 1);
                if(--g[i][col] < 0)
                {
                    printf("-1\n");
                    return 0;
                }
            }
            mp[v].erase(col);
            mp[v - 1].insert(col);
            ++sum;
            op = s[1].begin();
            ed = --s[1].end();
            //  printf("%d %d\n", *op, *ed);
        }
        for(int i = 1; i <= r; ++i)
        {
            op = s[i].begin();
            ed = --s[i].end();
            if(*op < *ed)
            {
                printf("-1\n");
                return 0;
            }
            ansr[i] = *op;
            sum += ansr[i];
        }

        printf("%d\n", sum);
        for(op = ansl.begin(); op != ansl.end(); ++op)
            printf("col %d\n", *op);
        for(int i = 1; i <= r; ++i)
        {
            for(int j = 1; j <= ansr[i]; ++j)
            {
                printf("row %d\n", i);
            }
        }
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值