Codeforces Round #311 (Div. 2) A B C D

来源:互联网 发布:阿里云企业邮箱客户端 编辑:程序博客网 时间:2024/06/08 15:30

A - Ilya and Diplomas给出三种奖项的上下限,使一等,二等,三等的数量依次尽量多。求分配方案

int main(){    int n;    int l1, r1, l2, r2, l3, r3;    while( ~scanf("%d%d%d%d%d%d%d", &n, &l1, &r1, &l2, &r2, &l3, &r3 ) ) {        int c1, c2, c3;        c1 = min( r1, n - l2 - l3 );        n -= c1;        c2 = min( r2, n - l3 );        n -= c2;        c3 = n;        printf("%d %d %d\n", c1, c2, c3);    }    return 0;}
B - Pasha and Tea给出2*n个茶杯的容量与水壶的容量,然后分给n男n女,使每个男的喝到的茶是某个女的的两倍(一一对应)。问最多能喝多少茶

const int N = 100010;ll a[N<<1];int main(){    ll n, m;    while( cin >> n >> m ) {        for( int i = 1; i <= n*2; ++i ) {            cin >> a[i];        }        sort( a+1, a+1+n*2 );        double ans = (double)min( 1.0 * a[1], 1.0 * a[1+n]/2 ) * 3 * n;        ans = min( ans, (double) m );        printf("%.13f\n", ans);    }    return 0;}

C - Arthur and Table给出一张桌腿长短不一的桌子,求最小的代价锯掉一些桌腿使桌子稳定,桌子稳定的条件是最长的长度的桌腿数量在一半以上。

枚举桌腿长度,然后根据长度计算代价即可

#include <map>#include <set>#include <queue>#include <stack>#include <vector>#include <string>#include <math.h>#include <time.h>#include <stdio.h>#include <iomanip>///cout << fixed << setprecision(13) << (double) x << endl;#include <stdlib.h>#include <string.h>#include <iostream>#include <algorithm>using namespace std;#define lson l, mid, rt << 1#define rson mid + 1, r, rt << 1 | 1#define ls rt << 1#define rs rt << 1 | 1#define pi acos(-1.0)#define eps 1e-8#define asd puts("sdfsdfsdfsdfsdfsdf");typedef long long ll;typedef __int64 LL;const int inf = 0x3f3f3f3f;const int N = 100010;int dsum[N];int Hash[222];int cnt[N];int n;map <int, int> high;map <int, int> :: reverse_iterator it;vector <int> v[N];struct node{    int l, d;}a[N];int main(){    while( ~scanf("%d", &n) ) {        high.clear();        memset( dsum, 0, sizeof( dsum ) );        memset( Hash, 0, sizeof( Hash ) );        for( int i = 1; i <= N-10; ++i )            v[i].clear();        for( int i = 1, l; i <= n; ++i ) {            scanf("%d", &l);            a[i].l = l;            high[l]++;        }        for( int i = 1, d; i <= n; ++i ) {            scanf("%d", &d);            a[i].d = d;            dsum[a[i].l] += d;            Hash[d]++;            v[a[i].l].push_back(d);        }        int ans = inf, cut_num = 0, cur_cost = 0;        for( it = high.rbegin(); it != high.rend(); ++it ) {            int l = it->first, cnt = it->second;            int x = n - cut_num;    //left            for( int i = 0; i < v[l].size(); ++i ) {                int c = v[l][i];                Hash[c]--;            }            if( cnt * 2 > x ) {                ans = min( ans, cur_cost );            }            else {                int tmp = cur_cost;                for( int i = 1; i <= 200; ++i ) {                    if( !Hash[i] )                        continue;                    if( x - Hash[i] >= 2 * cnt ) {                        tmp += i * Hash[i];                        x -= Hash[i];                    }                    else {                        tmp += (x - ( 2*cnt - 1 ) ) * i;                        break;                    }                }                ans = min( ans, tmp );            }            cut_num += cnt;            cur_cost += dsum[l];        }        printf("%d\n", ans);    }    return 0;}

D - Vitaly and Cycle给出一张图,添加最少的边使图里能够构成奇数点的圈,并输出添加边的方案数。

可以想到,最多添加三条边就足以构成一个奇数圈,而且注意到,当需要添加的边数为0 2 3的时候都是可以特判出来的。那么只需要去计算添加边数为1 的情况,即1-2-3-4-5-6...这种情况。很明显,添加的边相连的两点中间至少要隔一个点。用bfs染色然后累加情况就行了

#include <map>#include <set>#include <queue>#include <stack>#include <vector>#include <string>#include <math.h>#include <time.h>#include <stdio.h>#include <iomanip>///cout << fixed << setprecision(13) << (double) x << endl;#include <stdlib.h>#include <string.h>#include <iostream>#include <algorithm>using namespace std;#define lson l, mid, rt << 1#define rson mid + 1, r, rt << 1 | 1#define ls rt << 1#define rs rt << 1 | 1#define pi acos(-1.0)#define eps 1e-8#define asd puts("sdfsdfsdfsdfsdfsdf");typedef long long ll;typedef __int64 LL;const int inf = 0x3f3f3f3f;const int N = 100010;struct node{    int v, nxt;}e[N<<1];int head[N];int n, m, cnt;int deg[N];int vis[N];ll ans;bool OK;queue <int> q;void init(){    OK = ans = cnt = 0;    memset( vis, -1, sizeof( vis ) );    memset( head, -1, sizeof( head ) );    memset( deg, 0, sizeof( deg ) );}void add( int u, int v ){    e[cnt].v = v;    e[cnt].nxt = head[u];    head[u] = cnt++;    e[cnt].v = u;    e[cnt].nxt = head[v];    head[v] = cnt++;}void bfs( int st ){    int z = 0, o = 1;    vis[st] = 1;    while( !q.empty() ) q.pop();    q.push( st );    while( !q.empty() ) {        int u = q.front();        q.pop();        for( int i = head[u]; ~i; i = e[i].nxt ) {            int v = e[i].v;            if( vis[v] == -1 ) {                vis[v] = (!vis[u]);                q.push(v);                if( vis[v] == 1 )                    o++;                else                    z++;            }            else {                if( vis[v] == vis[u] ) {                    OK = 1;                    return;                }            }        }    }    ans += 1LL * z * (z-1) / 2;    ans += 1LL * o * (o-1) / 2;}int main(){    while( ~scanf("%d%d", &n, &m) ) {        init();        int maxd = 0;        for( int i = 1, u, v; i <= m; ++i ) {            scanf("%d%d", &u, &v);            add( u, v );            deg[v]++, deg[u]++;            maxd = max( maxd, max( deg[u], deg[v] ) );        }        if( m == 0 ) {            printf("3 %lld\n", 1LL * n * (n-1) * (n-2) / 6 );            continue;        }        if( maxd == 1 ) {            printf("2 %lld\n", 1LL * m * (n-2) );            continue;        }        for( int i = 1; i <= n; ++i ) {            if( vis[i] == -1 )                bfs( i );            if( OK )                break;        }        if( OK )            puts("0 1");        else            printf("1 %lld\n", ans);    }    return 0;}


0 0