码迷,mamicode.com
首页 > 其他好文 > 详细

POJ - 3484 Showstopper 二分搜索

时间:2015-05-14 01:00:04      阅读:149      评论:0      收藏:0      [点我收藏+]

标签:

题目大意:给出N个X Y Z组合,其中X Y Z组合能够输出 X, X + Z, X + 2 * Z… X + K * Z(X+K * Z <= Y)问这些输出的数中,有哪个数是输出奇数次的

解题思路:输出保证最多只有一个奇数
假设J是输出奇数次的那个数,那么小于J的所有输出的数的个数之和就为偶数,大于等于J的所有输出的数的个数之和为奇数
如果以i为标准,输出小于等于i的所有数之和,i从小到大变化的话,就会有如下的形式
偶偶偶偶偶偶奇奇奇。。。第一个奇刚好是J
(具体的可以自己验证)
通过上面的规律,就可以通过二分搜索来求得J了

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
#define maxn 50010
typedef long long ll;
ll X[maxn], Y[maxn], Z[maxn];
int cnt;
char str[maxn];

ll judge(ll mid) {
    ll Sum = 0;
    for(int i = 0; i < cnt; i++) {
        if(mid < X[i])
            continue;
        ll t = min(mid, Y[i]);
        Sum += (t - X[i])/ Z[i] + 1;
    }
    return Sum;
}

void solve() {
    cnt = 1;
    X[0] = 0;
    sscanf(str,"%lld%lld%lld", &X[0], &Y[0], &Z[0]);
    if(!X[0])
        return ;

    while(gets(str) && str[0]) {
        sscanf(str,"%lld%lld%lld", &X[cnt], &Y[cnt], &Z[cnt]);
        cnt++;
    }

    ll l = 0, r = 1LL << 32;
    while(l < r) {
        ll mid = (l + r) / 2;
        if(judge(mid) % 2)
            r = mid;
        else
            l = mid + 1;
    }
    if(l == (1LL << 32))
        printf("no corruption\n");
    else
        printf("%lld %lld\n",l, judge(l) - judge(l - 1));
}

int main() {
    while(gets(str))
        solve();
    return 0;
}

POJ - 3484 Showstopper 二分搜索

标签:

原文地址:http://blog.csdn.net/l123012013048/article/details/45704375

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!