二分题目总结

来源:互联网 发布:微信公众平台程序 mac 编辑:程序博客网 时间:2024/06/05 19:00

在UVA上搜索二分时搜到了一个很好的public专题

1.POJ - 3258 River Hopscotch
http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=16277

解题思路:http://blog.csdn.net/l123012013048/article/details/45646911
这题是符合条件的情况下,解有可能是偏小的

2.POJ - 3273 Monthly Expense
http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=14546

解题思路:http://blog.csdn.net/l123012013048/article/details/45648269
这题是符合条件的状况下,解是偏大的的

3.POJ - 3104 Drying
http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=16416

解题思路:http://blog.csdn.net/l123012013048/article/details/45652769

4.POJ - 2976 Dropping tests
http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=17097

解题思路:http://blog.csdn.net/l123012013048/article/details/45675971

5.POJ - 3111 K Best
http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=39448

解题思路:http://blog.csdn.net/l123012013048/article/details/45672533

6.POJ - 3579 Median
http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=24230

解题思路:http://blog.csdn.net/l123012013048/article/details/45675807

7.POJ - 3685 Matrix
http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=24239

题目大意:给出一个n * n的矩阵,其中Aij = i * i + 100000 × i + j * j - 100000 × j + i × j,求这个矩阵中第M小的数是多少

解题思路:二分求地M小的数
观察这个式子,可以发现随着i增加,Aij也相应的增加,有这个性质可以判断一下有多少每一列有多少个是小于等于这个数的了

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;#define INF 0x3f3f3f3ftypedef long long ll;ll N, M;ll Count(int i, int j) {    return ll(i + 100000 + j) * i + ll(j - 100000) * j;}bool judge(ll mid) {    ll cnt = 0;    for(int j = 1; j <= N; j++) {        int l = 1, r = N;        while(l <= r) {            int Mid = (l + r) / 2;            if( Count(Mid,j) <= mid)                l = Mid + 1;            else                r = Mid - 1;        }        cnt += l - 1;    }    return cnt < M;}ll solve() {    ll l = -((ll)N * N * 3 + 100000 * N) , r = (ll)N * N * 3 + 100000 * N;    while(l <= r) {        ll mid = (l + r) / 2;         if(judge(mid))            l = mid + 1;        else            r = mid - 1;    }    return l;}int main(){    int test;    scanf("%d", &test);    while(test--) {        scanf("%lld%lld", &N, &M);        printf("%lld\n",solve());    }    return 0;}

8.POJ - 3484 Showstopper
http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=15091
题目大意:有n组 X Y Z的组合,X Y Z组合可以输出X , X + Z , X + 2 Z , … X + K Z(X + K * Z <= Y)
要求你找出那个输出次数为奇数的数,并求出输出了几次
解题思路:那个输出奇数次的数之前的数的总和肯定为偶数,也就是说他是满足这样的规律的
偶偶偶偶偶偶奇奇奇。。。先偶数后奇数的

#include<cstdio>#include<algorithm>#include<cstring>using namespace std;#define maxn 50010typedef 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;}
0 0
原创粉丝点击