您的位置:首页 > 其它

Codeforces Round 311 div2

2015-07-02 08:09 260 查看
总计:

虽然被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数组值减一。于是过了。

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

源码:

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
){

ans = data[0];

ans = ans * 3 * n;

if(ans > w)

ans = w;

}

else{

ans = data
;

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
;

int res = sum
;

// 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

*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: