Codeforces Round 311 div2

来源:互联网 发布:ubuntu把文件压缩到u盘 编辑:程序博客网 时间:2024/04/29 09:31

总计:

虽然被skipped了,但是也近乎独立做了两题。心情不错。

直接上B题。水题。然而比赛中交的代码是错误的,主要是输出格式问题。题目要求输出浮点数,但是没说怎么处理尾0。而cout是可以自动去除尾0的,printf就不可以。然而问题是,当ans大些时,cout会输出科学记数法,导致答案错误。而不要求精度(实际上本题要求1e-6)。这时候就是做题经验的问题了,输出的不一定要和样例完全一样,简单printf即可

C题,排序检索题,单刷很久。给一些凳子脚的长度和去除该凳子脚需要的代价。求最小代价使得最大凳子脚的个数超过剩余个数的1/2

因为凳子脚的长度在1-200的范围内,所以想到枚举最大凳子脚。假设当前枚举的凳子脚长度为l,则需要预处理长度大于L的凳子脚都要去掉,并且长度为L的凳子脚都不能去掉(易证),在长度小于L的凳子脚中找最小代价。按照凳子脚长度排序,用sum数组统计长度大于L的代价和。

枚举长度小于L的凳子脚的时候T了。刚开始使用容器来存每种长度对应的下标。T后穷举。又T,然后想到新办法。用dd数组存所有代价的初始个数。每往下移动一个就减去当前凳子脚代价的dd数组值减一。于是过了。

找个时间补一补DED好像是简单图论题,我觉得图论不能再这样水下去了。

源码:

B

#include <cstdio>

#include <cmath>

#include <cstring>

#include <algorithm>

#include <iostream>

#include <string>

#include <queue>

using namespace std;

const int MAXN = 1e5;

int data[MAXN*2+5];

bool cmp(int a,int b){return a<b;}

int main()

{

    int n,w;

    while(scanf("%d%d",&n,&w) != EOF){

        for(int i=0; i<2*n; i++)

            scanf("%d",&data[i]);

        sort(data,data+2*n,cmp);

        double ans = 0;

        if(data[0] * 2 < data[n]){

            ans = data[0];

            ans = ans * 3 * n;

            if(ans > w)

                ans = w;

        }

        else{

            ans = data[n];

            ans = ans / 2 * 3 * n;

            if(ans > w)

                ans = w;

        }

        printf("%f\n",ans);

//        cout<<ans<<endl;

    }

    return 0;

}

 

C

#include <cstdio>

#include <cmath>

#include <cstring>

#include <string>

#include <algorithm>

#include <iostream>

#include <vector>

#define gmax(a,b) a>b?a:b

#define gmin(a,b) a<b?a:b

using namespace std;

const int MAXN = 1e5+5;

struct D

{

    int l,d;

}lv[MAXN];

int dd[200+5];

bool cmp1(D a,D b)///first l up,second d down

{

    if(a.l != b.l)

        return a.l>b.l;

    return a.d < b.d;

}

bool cmp2(D a,D b)

{

    return a.d < b.d;

}

int sum[MAXN];

int main()

{

    int n;

    while(scanf("%d",&n) != EOF){

        memset(dd, 0, sizeof(dd));

        for(int i=1; i<=n; i++){

            scanf("%d",&lv[i].l);

        }

        for(int i=1; i<=n; i++){

            scanf("%d",&lv[i].d);

            dd[lv[i].d]++;

        }

        sort(lv + 1, lv + n + 1, cmp1);

        sum[0] = 0;

        for(int i=1; i<=n; i++){

            if(i == 1)

                sum[i] = lv[i].d;

            else

                sum[i] = sum[i-1] + lv[i].d;

        }

//        int f = 1;

        int pre = 0;

        int ans = sum[n];

        int res = sum[n];

//        for(int i=1; i<=n; i++)

//            printf("for i = %d,lv[i].d = %d,lv[i].l = %d\n",i,lv[i].d,lv[i].l);

        dd[lv[1].d]--;

        for(int i=2; i<=n+1; i++){

            if(lv[i].l != lv[i-1].l || i == n+1){

//                printf("i = %d\n",i);

                int now = i - 1;

                int len = n - pre - 2 * (now - pre) + 1;

//                printf("i = %d,pre = %d\n",i,pre);

//                printf("len = %d\n",len);

                res = sum[pre];

//                printf("first res = %d\n",res);

                if(len <= 0){

                    ans = gmin(ans, res);

                    break;

                }

                for(int j=1; j<=200; j++){

                    if(dd[j] >= len){

                        res += j * len;

                        len = 0;

                    }

                    else{

                        res += dd[j] * j;

                        len -= dd[j];

                    }

                    if(len <= 0)

                        break;

                }

                pre = now;

            }

            dd[lv[i].d]--;

            ans = gmin(res, ans);

        }

 

        printf("%d\n",ans);

    }

    return 0;

}

/*

2

1 5

3 2

*/

 

0 0
原创粉丝点击