美团笔试第三场8.26
分享题解攒人品捏
1,题意:美团可以给树浇水,树成长x点,同时可以施肥,树成长y点,施肥需要间隔2两天,求到z点成长值的最少天数(1e9)
假设最少要n天,有
,二分或者直接解都可以
2,n个账单,m个人,每次给出账单信息——k个人一共花了c元,每个要付 ,求每个人要付多少(1e5)
模拟即可
3,n个数,k次操作,每次操作是选两个数ai,aj,然后变成x,y,条件是ai * aj = x * y,求最后n个数和最大值
对n个数排序后,显然是尽量把大的数乘到an中去,模拟一下,最后求和即可
4,重排两个数组(长500,值域[-500,500]),使得每个位置符合ai + bi ∈[1,m],m是给的
重排两个数组,等价于固定住一个数组,另一个变化。先对两个数组排序,然后固定住a,看b数组,对于a的每个位置i,b可以求出一个范围[l,r],使得任意j∈[l,r]满足ai + bj ∈[1,m]举个例子
m = 3
a:1,2,3
b:1,2,3
对于a中第一个位置a=1,b中1,2,3是满足的;a=2,b中1是满足,可以发现b中满足的数总是一个区间。
那对a中每个位置都求出b中一个合法区间,然后问题就转化成经典问题:n个区间限制,每个限制里只能取一个数,最后是否能全部取完
对于这个问题,贪心解决即可。我们对n区间按照r排序,再按照l排序,然后遍历每条限制,每次取最小的且满足大于等于l的位置i即可,有一次不能取到则判断为No(所以这题数据范围可以拉更大,500的话是有dp做法吗,暂时想不到,求大佬知道的话求留言捏)
讲的可能不是很明白,贴下代码
#define int long long
using namespace std;
const int N = 5e2+10;
const int mod = 1e9+7;
int n,m,k;
int a[N],b[N];
array<int,2> line[N];
void solve(){
set<int> st;
cin >> n >> m;
for(int i=1;i<=n;i++){
cin >> a[i];
st.insert(i);
}
for(int i=1;i<=n;i++){
cin >> b[i];
}
sort(a+1,a+1+n);
sort(b+1,b+1+n);
int flag = 1;
for(int i=1;i<=n;i++){
if(a[i]+b[n] < 1)
flag = 0;
if(a[i]+b[1] > m)
flag = 0;
int p1 = lower_bound(b+1,b+1+n,1-a[i]) - b;
int p2 = upper_bound(b+1,b+1+n,m-a[i]) - b - 1;
if(flag==0)
break;
line[i] = {p1,p2};
}
sort(line+1,line+1+n,[&](auto A,auto B){
return A[1] != B[1] ? A[1] < B[1] : A[0] < B[0];
});
for(int i=1;i<=n;i++){
auto [l,r] = line[i];
// cout << l << " " << r << endl;
auto it = st.lower_bound(l);
if(it==st.end() || it > r){
flag = 0;
break;
}
st.erase(it);
}
cout << (flag?"Yes":"No") << endl;
}
signed main() {
int T;cin>>T;
while(T--){
solve();
}
}
5,求一个最长区间,满足区间平均数为k
二分写到一半,看了眼样例发现假了。。。写一下公式,然后脑子又清醒了
设为前缀和i,我们要找的区间[l,r]要满足
拆一下有,,那么我们枚举r,然后每次找下是否有满足这个条件的最小l即可。注意初始化0
牛客markdown怎么一堆显示bug,只能贴图片了
#define int long long
using namespace std;
const int N = 2e5+10;
const int mod = 1e9+7;
int n,m,k;
int a[N],pre[N];
map<int,int> mp;
signed main() {
cin >> n >> k;
for(int i=1;i<=n;i++){
cin >> a[i];
pre[i] = pre[i-1] + a[i];
}
mp[0] = 0;
int ans = -1;
for(int i=1;i<=n;i++){
if(mp.count(pre[i]-k*i)){
ans = max(ans,i - mp[pre[i]-k*i]);
}
else {
mp[pre[i]-k*i] = i;
}
}
cout << ans;
}