您的位置:首页 > 其它

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

2015-09-02 19:28 375 查看
题目请点我

题解:

这道题是说有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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: