1、最小的最大值
牛牛有一个长度为n的正整数数组a={a1,a2,…,an},现在他可以执行下面的操作:
选择一个i(1<=i<=n),令ai=ai+1
他必须执行k次
上述的操作,牛牛想让执行完所有操作之后的数组a中的最大值尽可能的小
,请你帮助牛牛计算这个尽可能小的最大值。
示例1:
输入:
3 3
1 2 3
输出:
3
说明:
第1次操作:选择a1,令a1=a1+1=2,数组为{2,2,3}
第2次操作:选择a1,令a1=a1+1=3,数组为{3,2,3}
第3次操作:选择a2,令a2=a2+1=3,数组为{3,3,3}
示例2:
输入:
3 6
1 2 3
输出:
3
说明:
前3次操作同例1,数组变为{3,3,3}
接下来3次操作依次选择a1,a2,a3,最终数组变为{4,4,4},因此答案为4。
思路:每次在最小的数上进行加1操作。
(1)当所有与最大数的差之和大于或等于要操作的次数k时:最后的最大值就是初始最大值。因为,还未达到把所有的数变为一样。
(2)当所有与最大数的差之和小于要操作的次数k时:在没达到要操作的次数k之前,已经将所有的数变为一样;剩余的次数(k-sum),平均分配给每个数即可。这样最后的最大值就是(初始最大值+剩余次数 / 数组个数的向上取整)
原始版:
#include <iostream>
#include <cmath> // ceil()向上取整的所在头文件
#include <vector>
#include <algorithm>
using namespace std;
int main() {
int n,k;
cin>>n>>k;
vector<int> inputs(n);
for(int i=0;i<n;i++){
cin>>inputs[i];
}
sort(inputs.begin(),inputs.end());
float sum=0;
for(int i=0;i<n;i++){
sum+=inputs[inputs.size()-1]-inputs[i];
}
if(k<=sum){
cout<<inputs[inputs.size()-1]<<endl;
}
else if(k>sum){
float j=k-sum;
float m=inputs.size();
int res = ceil(j/m);
cout<<inputs[inputs.size()-1] + res<<endl;
}
return 0;
}
// 只通过52%
注意:要考虑数据溢出情况————用long类型
(长整型)!!!!!
x/y向上取整 等价于 (x+y-1)/y向下取整
修改版:
#include <iostream>
#include <cmath>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
int n;
long k;
cin>>n>>k;
vector<long> inputs(n);
for(int i=0;i<n;i++){
cin>>inputs[i];
}
sort(inputs.begin(),inputs.end());
long max = inputs[n-1];
long sum=0;
for(int i=0;i<n;i++){
sum += max-inputs[i];
}
if(k>sum){
k=k-sum;
max+=(k+n-1)/n; //实现向上取整
}
cout<<max<<endl;
return 0;
}
2、集合
牛牛的k支部队驻扎在一个 n * m 的矩形地图上,每只部队都驻扎在一个独一无二的坐标(i,j)(1<=i<=n,1<=j<=m)上(i,j都是整数)。
对于每一支部队,假设该部队当前的坐标为(i,j),则该部队可以花费1小时
从坐标(i,j)移动到(i+1,j),(i,j+1),(i-1,j),(i,j-1)这四个坐标的其中一个(即每次可向上、下、左、右移动),且该部队不能离开地图。
地图上还有一些整数坐标是沼泽,部队不能达到沼泽区域
。
现在牛牛要将这些部队集结到同一个坐标点
,集结总耗时为到达集结点最慢的部队的耗时
,牛牛想知道集结总耗时最短需要几小时
?
输入描述:
第一行输入两个正整数 n, m
表示矩阵地图的长和宽
。
接下来 n 行
,每行输入一个长度为 m 的只包含 ‘0’ 和 ‘1’ 的字符串
,如果第 i 行第 j 列的字符为‘1’
,则表示坐标(i,j)为沼泽
,如果第 i 行第 j 列的字符为‘0’
,则表示坐标(i,j)为陆地
(部队只能在陆地上,儿不能在沼泽上)。
接下来一行输入正整数 k
表示部队的数目
。
最后 k 行每行两个正整数 x,y表示部队驻扎的坐标为(x,y)
。
(1<=n,m<=500,1<=k<=min(10,n*m-S),1<=x<=n,1<=y<=m,其中S为沼泽区域的个数,数据保证初始部队的坐标不会和沼泽的坐标重合
。)
输出描述:
输出一个正整数表示集结总耗时最短需要几个小时,如果所有的部队无法集结到一块,则输出-1。
示例1:
输入:
3 3
000
101
000
4
1 1
1 3
3 1
3 3
输出:
2
说明:部队从(1,1),(1,3),(3,1),(3,3)出发到(2,2)耗时均为2,最终集合时间为2,因此答案为2。
示例2:
输入:
3 3
000
111
000
2
1 2
3 2
输出:
-1
说明:两支队伍无法集合在一起。
思路:每个军队同时做广度优先遍历,看是否能够聚集在一起?
首先求每个军队到达地图任何一个地方的最短时间,然后遍历所有地点,计算所有军队到达这里的最大值,这些最大值中的最小值即为所求。
招银科技测开
1、题目:将一个数组按照1,2,3…递增的顺序用逗号分隔,如果最后剩余的个数不足以进行分隔,则省略。
例1:[1 2 3 4 5 6]
输出[1],[2 3],[4 5 6]
例2:[1 2 3 4]
输出:[1],[2 3]
思想:
1、记录 j 为递增序列中的每一项,初始为1;
2、循环遍历数组:
如果剩余的元素个数 < 当前要分隔的个数,则结束循环;
将当前要分隔的数存放在一个数组中。将遍历的下标通过加 j,移动到下次要分隔的位置。
#include <iostream>
#include <vector>
using namespace std;
vector<vector<int>> get_in(vector<int>&L){
vector<vector<int>> result;
int j=1;
int n=L.size();
for(int i=0;i<n;){
if(n-i-j<0) break; //!!!笔试时是写错了。心塞
int k=0;
vector<int> tmp;
while(k<j){
tmp.push_back(L[i+k]);
k++;
}
result.push_back(tmp);
i += j;
j++;
}
return result;
}
int main() {
vector<int> inputs;
int x;
while(cin>>x){
inputs.push_back(x);
}
vector<vector<int>> res = get_in(inputs);
for(int i=0;i< res.size();i++){
cout << "[";
for(int j=0;j<res[i].size();j++)
cout<<res[i][j]<<",";
cout<<"]";
}
return 0;
}