2024.08.31美团
1. 小美的姓名统计
小美写单词喜欢横着写,她记录了若干个人的名字,但是不小心加进去了一些无关的单词。
一个名字单词以大写字母开头,请你帮助她统计共有多少个人的名字。
简单输入处理
int main() {
string cur;
int res = 0;
while(cin>>cur){
if(cur[0]>='A'&&cur[0]<='Z') res++;
if(cin.get()=='\n') break;
}
cout<<res<<endl;
return 0;
}
2. 小美种树
长度无限长的公路上,小美雇佣了 n 位工人来种树,每个点最多种一棵树。
从左向右数,工人所站的位置为 a1,a2,...,an 。已知每位工人都会将自己所在位置的右侧一段长度的区间种满树,且每位工人的种树区间长度相同。
现在小美希望公路上至少有 k棵树,为了节约成本,他希望每位工人种树的区间长度尽可能短,请你帮他求出,工人们的种树区间至少多长,才能使得公路被种上至少 k棵树。
简单二分
int main() {
int n,k;
cin>>n>>k;
vector<int> pos(n);
for(int i=0;i<n;i++)
cin>>pos[i];
sort(pos.begin(),pos.end());//排序方便扫描
int l = 1; int r = k;
while(l<r){
int m = (l+r)/2; //每个人种m颗树
int total = 0;
int prepos = -1;//上一区域的右边界
for(int i=0;i<n;i++){//根据位置计算,假如是1,2,3,4,5
total += m;//种植m颗
if(prepos>=pos[i]) total -= (prepos-pos[i]+1);
prepos = pos[i]+m-1;//右边界
}
if(total>=k) r = m;//满足条件,移动
else l = m + 1;//不满足条件,增加
}
cout<<r<<endl;
return 0;
}
3. 小美和小团的游戏
小美和小团在玩一个游戏,游戏中有一个长度为 n 的数组 a ,她们会玩 q 轮游戏,每轮游戏都是独立的。
游戏规则如下,双方都会执行最优策略:
1) 第一步,游戏给出一个区间 [l,r]。
2) 第二步,小团在 [l,r] 区间中选择一个数。
3) 第三步,小美将区间扩展成 [L,R] ( [L,R] 必须包含 [l,r] ),然后在 [L,R] 区间中选择一个数,但不能跟小团选同一个数。
4) 第四步,小美和小团选择的数字较大的一方获胜,若相同则平局。
小美想知道她每一轮的输赢状态,并且她想知道要达到输赢状态所需的 [L,R] 区间长度最小是多少。
小团必然会选[l,r]中最大的数,对于小美,找l左侧下一个更大值下标,以及右侧下一个更大值下标,两者更近的为需要拓展的边界,这里使用单调栈预先计算,
如果没有,则是判断整个数组是否至少有两个该最大值,使用哈希计数即可,对于找[l,r]中的最大值,可以使用线段树,同时记录其下标