Codeforces #320(div2)

本文解析了五道经典编程题目,包括细菌繁殖、团队组建、折线问题、或运算游戏及弱点与贫弱值等,提供了详细的算法思路与实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

A. Raising Bacteria

题意: 每次放1 每天翻1倍  问放几个恰好达到n

分析: 考虑快速幂 - - 然后就可以了 其实直接__builtin_popcount(x)就是答案

代码:

//
//  Created by TaoSama on 2015-09-16
//  Copyright (c) 2015 TaoSama. All rights reserved.
//
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <algorithm>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <string>
#include <set>
#include <vector>

using namespace std;
#define pr(x) cout << #x << " = " << x << "  "
#define prln(x) cout << #x << " = " << x << endl
const int N = 1e5 + 10, INF = 0x3f3f3f3f, MOD = 1e9 + 7;

int n, ans;

void dfs(int x) {
    if(!x) return;
    if(x & 1) ++ans;
    dfs(x >>= 1);
}

int main() {
#ifdef LOCAL
    freopen("in.txt", "r", stdin);
//  freopen("out.txt","w",stdout);
#endif
    ios_base::sync_with_stdio(0);

    while(scanf("%d", &n) == 1) {
        ans = 0;
        dfs(n);
        printf("%d\n", ans);
    }
    return 0;
}


B. Finding Team Member
题意: 组成n队 然后按照题目信息给了一些组队信息 然后每次组队都得组最大的

分析: 排个序 标记下组过没 - - 然后记录答案

代码: 

//
//  Created by TaoSama on 2015-09-16
//  Copyright (c) 2015 TaoSama. All rights reserved.
//
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <algorithm>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <string>
#include <set>
#include <vector>

using namespace std;
#define pr(x) cout << #x << " = " << x << "  "
#define prln(x) cout << #x << " = " << x << endl
const int N = 1e5 + 10, INF = 0x3f3f3f3f, MOD = 1e9 + 7;

int n, ans[805];
struct P {
    int s, i, j;
    bool operator<(const P& rhs) const {
        return s > rhs.s;
    }
} a[800 * 800];

int main() {
#ifdef LOCAL
    freopen("in.txt", "r", stdin);
//  freopen("out.txt","w",stdout);
#endif
    ios_base::sync_with_stdio(0);

    while(scanf("%d", &n) == 1) {
        int cnt = 0;
        n <<= 1;
        for(int i = 2; i <= n; ++i) {
            for(int j = 1; j < i; ++j) {
                scanf("%d", &a[cnt].s);
                a[cnt].i = i;
                a[cnt].j = j;
//                printf("%d %d %d\n", a[cnt].s, a[cnt].i, a[cnt].j);
                ++cnt;
            }
        }
        sort(a, a + cnt);
        memset(ans, 0, sizeof ans);
        for(int i = 0; i < cnt; ++i) {
            P& cur = a[i];
//          printf("%d %d %d\n", cur.s, cur.i, cur.j);
            if(ans[cur.i] || ans[cur.j]) continue;

            ans[cur.i] = cur.j;
            ans[cur.j] = cur.i;
        }
        for(int i = 1; i <= n; ++i)
            printf("%d%c", ans[i], " \n"[i == n]);
    }
    return 0;
}

C. A Problem about Polyline

题意: /\/\/\/\ 这种形状 然后给一个(x,y)坐标 求这个坐标在上面的 最小的高

分析: 斜率是1 所以所在的端点是(x-y,0) 和 (x+y,0)  假设这个点在峰顶

          左边有c1=(x-y)/(2y)个周期  右边有c2=(x+y)/(2y)个周期

          然后(x-y) / c1 / 2就是答案 - - 

          x < y是显然没答案的  - - 特判下x==y 不然会输出除0输出nan

代码:

//
//  Created by TaoSama on 2015-09-16
//  Copyright (c) 2015 TaoSama. All rights reserved.
//
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <algorithm>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <string>
#include <set>
#include <vector>

using namespace std;
#define pr(x) cout << #x << " = " << x << "  "
#define prln(x) cout << #x << " = " << x << endl
const int N = 1e5 + 10, INF = 0x3f3f3f3f, MOD = 1e9 + 7;
const double EPS = 1e-10;

int x, y;

int main() {
#ifdef LOCAL
    freopen("in.txt", "r", stdin);
//  freopen("out.txt","w",stdout);
#endif
    ios_base::sync_with_stdio(0);

    while(scanf("%d%d", &x, &y) == 2) {
        if(x < y) puts("-1");
        else if(x == y) printf("%.12f\n", 1.0 * x);
        else {
            double k1 = x - y, k2 = x + y;
            int c1 = k1 / 2 / y, c2 = k2 / 2 / y;
            double ans = min(k1 / 2 / c1, k2 / 2 / c2);
            printf("%.12f\n", ans);
        }
    }
    return 0;
}

D. "Or" Game

题意: 给定一个序列a1,a2,...an 现在可以最多乘k次x 之后 求整个序列的最大xor值

分析: 显然肯定乘到一个上面最优 但是要枚举乘的数 不能乘最大的 有反例

          比如:

                  3 1 2

                  4 5 2

           要乘到4上面而不是5

代码: 

//
//  Created by TaoSama on 2015-09-17
//  Copyright (c) 2015 TaoSama. All rights reserved.
//
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <algorithm>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <string>
#include <set>
#include <vector>

using namespace std;
#define pr(x) cout << #x << " = " << x << "  "
#define prln(x) cout << #x << " = " << x << endl
const int N = 2e5 + 10, INF = 0x3f3f3f3f, MOD = 1e9 + 7;

int n, k, x;
long long a[N], l[N], r[N];

int main() {
#ifdef LOCAL
    freopen("in.txt", "r", stdin);
//  freopen("out.txt","w",stdout);
#endif
    ios_base::sync_with_stdio(0);

    while(scanf("%d%d%d", &n, &k, &x) == 3) {
        l[0] = r[n + 1] = 0;
        for(int i = 1; i <= n; ++i) {
            scanf("%I64d", a + i);
            l[i] = l[i - 1] | a[i];
        }
        for(int i = n; i; --i)
            r[i] = r[i + 1] | a[i];

        long long ans = 0;
        for(int i = 1; i <= n; ++i) {
            long long cur = l[i - 1] | r[i + 1], tmp = a[i];
            for(int j = 1; j <= k; ++j) tmp *= x;
            ans = max(ans, cur | tmp);
        }
        printf("%I64d\n", ans);
    }
    return 0;
}

E. Weakness and Poorness

题意: 求一个东西 然后自己看题吧 - - 反正就四行

分析: 赛上健忘症又犯了 读题忘 一开始check里面写的max 然后读了output发现是求min然后就改成了min

          也不想想刚才自己过了样例啊 - - 肯定是没写错的 这种时候应该 通读一遍题啊 一直以为三分写错了 简直逗比 不然是可以过的啊

 绝对值函数是凸函数 然后凸函数的max也是凸函数 (详情见百度百科 这里我是一直记的结论)

          好吧 很显然 应该是三分 然后让你求的东西明显是最大子串和 dp就好了 因为是绝对值 把负数的也搞一遍 

          三分范围别忘记了负的

代码:

//
//  Created by TaoSama on 2015-09-17
//  Copyright (c) 2015 TaoSama. All rights reserved.
//
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <algorithm>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <string>
#include <set>
#include <vector>

using namespace std;
#define pr(x) cout << #x << " = " << x << "  "
#define prln(x) cout << #x << " = " << x << endl
const int N = 2e5 + 10, INF = 0x3f3f3f3f, MOD = 1e9 + 7;
const double eps = 1e-8;

int n;
double a[N], b[N];

double check(double x) {
    for(int i = 1; i <= n; ++i) b[i] = a[i] - x;
    double sum = 0, ans1 = 0, ans2 = 0;
    for(int i = 1; i <= n; ++i) {
        sum += b[i];
        if(sum > ans1) ans1 = sum;
        if(sum < 1e-10) sum = 0;
    }
    sum = 0;
    for(int i = 1; i <= n; ++i) {
        sum += b[i];
        if(sum < ans2) ans2 = sum;
        if(sum > 1e-10) sum = 0;
    }
    return max(ans1, -ans2);
}

int main() {
#ifdef LOCAL
    freopen("in.txt", "r", stdin);
//  freopen("out.txt","w",stdout);
#endif
    ios_base::sync_with_stdio(0);

    while(scanf("%d", &n) == 1) {
        for(int i = 1; i <= n; ++i) scanf("%lf", a + i);

        double l = -1e10, r = 1e10;
        for(int i = 1; i <= 300; ++i) {
            double ll = (l + r) / 2, rr = (ll + r) / 2;
            if(check(ll) < check(rr)) r = rr;
            else l = ll;
        }
//        printf("%.10f\n", l);
        printf("%.10f\n", check(l));
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值