首页 > 其他 > 详细

Codeforces Round #502 (in memory of Leopoldo Taravilse, Div. 1 + Div. 2)

时间:2019-11-21 21:53:45      阅读:115      评论:0      收藏:0      [点我收藏+]

A - The Rank

题意:定义排名为:先排总分,总分相同排id,求id为1的人的rnk。

题解:implement

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

pair<int, int> p[1005];

void test_case() {
    int n;
    scanf("%d", &n);
    for(int i = 1; i <= n; ++i) {
        int sum = 0;
        for(int j = 1, x; j <= 4; ++j) {
            scanf("%d", &x);
            sum += x;
        }
        p[i] = {-sum, i};
    }
    sort(p + 1, p + 1 + n);
    for(int i = 1; i <= n; ++i) {
        if(p[i].second == 1) {
            printf("%d\n", i);
            return;
        }
    }
}

int main() {
#ifdef KisekiPurin
    freopen("KisekiPurin.in", "r", stdin);
#endif // KisekiPurin
    int t = 1;
    for(int ti = 1; ti <= t; ++ti) {
        //printf("Case #%d: ", ti);
        test_case();
    }
}

B - The Bits

题意:有两个01串a,b,求交换a串的一对01位之后使得a|b的值变化的数量。

题解:分类讨论。显然同种字符换是没有意义的。假如某个ai=1且bi=1,那么需要把ai和某个aj=0且bj=0互换。假如某个ai=1且bi=0,那么需要把ai和某个aj=0互换。假如某个ai=0且bi=1,那么可以和aj=1且bj=0互换。假如某个ai=0且bi=0,那么可以和aj=1互换。

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

int a[100005], b[100005];
int cnt[2][2];

void test_case() {
    int n;
    scanf("%d", &n);
    for(int i = 1; i <= n; ++i)
        scanf("%1d", &a[i]);
    for(int i = 1; i <= n; ++i) {
        scanf("%1d", &b[i]);
        ++cnt[a[i]][b[i]];
    }
    ll sum = 0;
    for(int i = 1; i <= n; ++i) {
        if(a[i] == 0 && b[i] == 0)
            sum += cnt[1][0] + cnt[1][1];
        else if(a[i] == 0 && b[i] == 1)
            sum += cnt[1][0];
        else if(a[i] == 1 && b[i] == 0)
            sum += cnt[0][0] + cnt[0][1];
        else
            sum += cnt[0][0];
    }
    printf("%lld\n", sum / 2);
}

int main() {
#ifdef KisekiPurin
    freopen("KisekiPurin.in", "r", stdin);
#endif // KisekiPurin
    int t = 1;
    for(int ti = 1; ti <= t; ++ti) {
        //printf("Case #%d: ", ti);
        test_case();
    }
}

C - The Phone Number

题意:给一个n,构造一个[1,n]排列,使得最长严格上升子序列长度+最长严格下降子序列长度最小。

考虑样例的构造法,比如n=6:

456123

上升为3,下降为2。

564312

上升为2,下降为3。

其中下界肯定是2,这个毫无疑问,那么3能不能变小?要使得上升最小,必须把二元组这样编排(除非搞个全部降序,上升就是1,下降就是n),这样做下降的长度就是n/2。

大胆猜测是不是分成根号n组呢?

789456123

这样下降是3,上升也是3。看样子,把其中一个长度控制在x,就要分成n/x组,且组之间逆序排列。不会证明,先莽一发。

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

int ans[100005];

void test_case() {
    int n;
    scanf("%d", &n);
    int L = sqrt(n);
    int R = L + 1;
    int cntR = n % L;
    int cntL = (n - R * cntR) / L;
    int top = 0, cur = n;
    for(int i = 1; i <= cntL; ++i) {
        int ccur = cur - L + 1;
        for(int j = 1; j <= L; ++j)
            ans[++top] = ccur++;
        cur -= L;
    }
    for(int i = 1; i <= cntR; ++i) {
        int ccur = cur - R + 1;
        for(int j = 1; j <= R; ++j)
            ans[++top] = ccur++;
        cur -= R;
    }
    for(int i = 1; i <= n; ++i)
        printf("%d%c", ans[i], " \n"[i == n]);
}

int main() {
#ifdef KisekiPurin
    freopen("KisekiPurin.in", "r", stdin);
#endif // KisekiPurin
    int t = 1;
    for(int ti = 1; ti <= t; ++ti) {
        //printf("Case #%d: ", ti);
        test_case();
    }
}

关于这种LIS的性质好像不太熟练,都是看直觉?

Codeforces Round #502 (in memory of Leopoldo Taravilse, Div. 1 + Div. 2)

原文:https://www.cnblogs.com/KisekiPurin2019/p/11908413.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!