CF_318_Div.2 Bear and Elections(二分||暴力枚举)

来源:互联网 发布:java enum 指定值 编辑:程序博客网 时间:2024/06/05 06:07

题目请点我

题解:

这道题是说有N个数,从后面N-1个数中挑出一部分加到第一个数,使第一个数成为N个数中最大的一个!

因为只能由后面的数添到第一个数上,所以结果只会和第一个数相对大小有关,最开始想用平均数,走错了思路。又因为题目确定了数的大小范围0~1000,最多只是1001,所以枚举第一个数的取值是一个不错的想法。枚举num[0]~1001,对于任意一个可能值i,如果其他N-1个数的值大于i-1的部分相加和小于等于i增加的值,则满足题意,因为不够的可以继续减,但是能保证其他所有数都小于第一个数。

枚举可以简单暴力去写,因为是找最优解,所以一旦满足条件就可以跳出。也可以二分去写,在写二分的时候很生疏,觉得还是没有很理解二分的思想,对于区间的控制和跳出的判断条件还要再好好想想,一下午搞了一道题,还是很开心到最后能搞懂。

代码实现:

二分:

#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>using namespace std;const int MAX = 1010;int N;int res = 0;int num[MAX];int main(){    scanf("%d",&N);    for( int i = 0; i < N; i++ ){        scanf("%d",&num[i]);    }    int left = num[0];    int right = MAX;    int mid = (left+right)>>1;    while( left<right ){        mid = (left+right)>>1;        int up = mid-num[0];        int down = 0;        for( int i = 1; i < N; i++ ){            if( num[i] > mid-1 ){                down += (num[i]-mid+1);            }        }        if( up >= down ){            right = mid;        }        else{            left = mid+1;        }    }    printf("%d\n",left-num[0]);    return 0;}


暴力枚举:

#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>using namespace std;const int MAX_N = 110;int N;int pos;int res;int flag,tmax;int num[MAX_N];bool check();int main(){    res = 0;    scanf("%d",&N);    for( int i = 0; i < N; i++ ){        scanf("%d",&num[i]);    }    for( int i = num[0]; i < 1002; i++ ){        int up = i-num[0];        int down = 0;        for( int j = 1; j < N; j++ ){            if( num[j] > i-1 ){                down += (num[j]-i+1);            }        }        if( up >= down ){            res = up;            break;        }    }    printf("%d\n",res);    return 0;}


0 0
原创粉丝点击