您的位置:首页 > 其它

[POJ2774]木材加工

2014-08-12 17:37 363 查看
描述

木材厂有一些原木,现在想把这些木头切割成一些长度相同的小段木头,需要得到的小段的数目是给定了。当然,我们希望得到的小段越长越好,你的任务是计算能够得到的小段木头的最大长度。

木头长度的单位是厘米。原木的长度都是正整数,我们要求切割得到的小段木头的长度也要求是正整数。

输入

第一行是两个正整数N和K(1 ≤ N ≤ 10000, 1 ≤ K ≤ 10000),N是原木的数目,K是需要得到的小段的数目。 接下来的N行,每行有一个1到10000之间的正整数,表示一根原木的长度。

输出

输出能够切割得到的小段的最大长度。如果连1厘米长的小段都切不出来,输出"0"。

思路:首先将木材按长度从小到大排序,然后用二分查找计算出最大长度。代码如下:

#include<iostream>
#include<cstdio>

using namespace std;

int* arr;
int n, k;

//快速排序
int cut(int* num, int lo, int hi){
int x = num[hi];
int mi = lo;
int temp;
for (int z=lo; z<hi; z++)
if (num[z] < x){
if (z != mi){
temp = num[mi];
num[mi] = num[z];
num[z] = temp;
}
mi++;
}
temp = num[hi];
num[hi] = num[mi];
num[mi] = temp;

return mi;
}

void sort(int* num, int lo, int hi){
if(lo < hi){
int x = cut(num, lo, hi);
sort(num, lo, x-1);
sort(num, x+1, hi);
}
}

//通过长度得出块数
int getCount(int length){
if(length == 0)
return 999999;
int count = 0;
for(int j=0; j<n; j++)
count += arr[j] / length;
return count;
}

//二分查找求最大长度
int binSearch(int lo, int hi){
int mi;
int maxLong;
if(lo < hi - 1){
mi = (lo + hi) >> 1;
int count = getCount(mi);
if(count >= k)
maxLong = binSearch(mi+1 , hi);
else
maxLong = binSearch(lo , mi-1);
return maxLong;
}
if(getCount(hi) >= k)
return hi;
return lo;
}

int main(){
std::ios::sync_with_stdio(false);
cin >> n >> k;
arr = new int
;
int sum = 0;
for(int i=0; i<n; i++){
cin >> arr[i];
sum += arr[i];
}
sort(arr, 0, n-1);
int max = sum / k;
int min = n > k ? arr[n-k] : 0;
int maxLong = binSearch(min, max);
cout << maxLong << endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: