【笔试训练】day3

 今天的题又简单了很多欸

1.简写单词

没思路

代码: 
#include <iostream>
#include<string>
using namespace std;

int main() {
    string  str;
    string ans;
    getline(cin,str);
    if(str[0]>'Z')ans+=(str[0]-32);
    else ans+=str[0];
    for(int i=1;i<str.size();i++){
        if(str[i]!=' '&&str[i-1]==' '){
            if(str[i]>'Z')ans+=(str[i]-32);
            else ans+=str[i];
        }
    }
   cout<<ans;

    return 0;
}

 2.dd爱框框

思路:

先维护一个前缀和s[].遍历每一个区间的左端点,去看看要想大于等于x 的最近右端点在哪

由于区间和(正数)是具有单调性,这里可以用二分。对于每个可能的左端点,都二分查找一个符合条件的最近右端点。 这样我们就能把所有符合答案的情况求出来了,再用一个变量维护最小长度,这个长度最终是所有可能符合答案中的最小值。

注意题目要求输出答案区间,所以我们还需要维护一个左端点就行了,左端点加上答案长度就是答案的右端点。

写完之后发现双指针就可以了草。用两个指针维护一个区间的左右端点嘛,如果当前区间和小于x,那就右端点移动。否则左端点移动,缩小答案区间。

二分代码:
#include <iostream>
using namespace std;
typedef long long ll;
const int N=1e7+10;
ll s[N];
int main() {
    int n;
    int x;
    cin>>n>>x;
    for(int i=1;i<=n;i++){
       int k;
       cin>>k;
       s[i]=s[i-1]+k;
    }
    int ans=1e9;
    int star=1;
    for(int i=1;i<=n;i++){
        int l=i-1;
        int r=n+1;
        while(l+1!=r){
            int mid=(l+r)>>1;
            if(s[mid]-s[i-1]>=x)r=mid;//符合条件放在右边,最后右边的第一个就是最小的右端点
            else l=mid;
        }
        if(s[r]-s[i-1]>=x){
            if(r-i+1<ans){
                ans=r-i+1;
                star=i;
            }
        }
    }
    cout<<star<<" "<<star+ans-1;
    return 0;
}

双指针代码:

#include <iostream>
using namespace std;
typedef long long ll;
const int N=1e7+10;
int a[N];
int main() {
    int n;
    int x;
    cin>>n>>x;
    for(int i=1;i<=n;i++){
       cin>>a[i];
    }
    int ans=1e9;
    int star=1;
    ll sum=0;
    for(int i=1,j=1;i<=n;i++){
       sum+=a[i];
        while(sum>=x){
            if(i-j+1<ans){
                ans=i-j+1;
                star=j;
            }
            sum-=a[j];
            j++;
        }
    }
    cout<<star<<" "<<star+ans-1;
    return 0;
}

3.除2!

 思路:

一眼看上去k很大,吓得我以为不能暴力了00

后来发现,一个int最大是2^32,即使这n个数都是一个最大的偶数,一共也最多被操作32*1e5

所以直接暴力枚举每次操作就行了。每次操作对最大的数除2,这样贡献才越大。用优先队列维护一下就行。

代码:
#include <iostream>
#include<queue>
using namespace std;

int main() {
    int n,k;
    cin>>n>>k;
    long long sum=0;//存总和
    priority_queue<int> q;
    while(n--){
        int x;
        cin>>x;
        sum+=x;
        if(x%2==0)q.push(x);//不是偶数直接滚
    }

    while(!q.empty()&&k){
       int it=q.top();
       q.pop();
       it/=2;
       sum-=it;
       k--;
       if(it%2==0)q.push(it);//不是偶数也没有再进去的必要了
    }
    cout<<sum;
    return 0;
}

  • 12
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值