【笔试训练】day3

简介: 【笔试训练】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;
}


相关文章
|
7月前
【笔试训练】day21
【笔试训练】day21
|
7月前
|
并行计算
【笔试训练】day14
【笔试训练】day14
|
7月前
|
人工智能
【笔试训练】day20
【笔试训练】day20
|
7月前
【笔试训练】day16
【笔试训练】day16
|
7月前
【笔试训练】day22
【笔试训练】day22
|
7月前
|
算法 Shell
【笔试训练】day12
【笔试训练】day12
|
7月前
【笔试训练】day23
【笔试训练】day23
|
7月前
|
人工智能 BI
【笔试训练】day24-day48合集(2)
【笔试训练】day24-day48合集(2)
|
7月前
|
人工智能
【笔试训练】day2
【笔试训练】day2

热门文章

最新文章