A:最大回撤

知识点:枚举

思路:枚举每个数值x,求出前i个数最大值与x的差值,n个差值中最大的那个就是答案(也就是,输入一个数,求出最大值,这个最大值就是前i个数的最大值,再减去每次输入的x就是商品最大可能的亏损价格)。

参考代码:

#include<bits/stdc++.h>
using namespace std;
int n,x,maxn=INT_MIN,ans=INT_MIN; 
int main(){
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>x;
        maxn=max(maxn,x);
        ans=max(ans,maxn-x);
    }
    if(ans==INT_MIN) cout<<0;
    else cout<<ans;
    return 0;
}

B:连续的零

知识点:字符串、滑动窗口法

思路:首先统计出前k个字符中出现1的个数,作为答案的初始值,其次指针从k+1开始走到n,每次都统计区间i-k+1到i区间的1的个数(也就是每次指针向后遍历一次,累加第i个位置的字符1,减去i-k个位置的字符1),随时取其最小值即可。

参考代码:

#include<bits/stdc++.h>
using namespace std;
int n,k,cnt,ans;
string s;
int main(){
    cin>>n>>k>>s;
    for(int i=0;i<k;i++){
        if(s[i]=='1'){
            cnt++;
        }
    }
    ans=cnt;
    for(int i=k;i<n;i++){
        cnt+=s[i]-s[i-k];
        ans=min(ans,cnt);
    }
    cout<<ans;
    return 0;
}

C:B进制星球

知识点:高精度、进制转换

思路:将输入的字符串倒序存储在数组中(注意大于等于16进制的情况),再利用高精度加法原理来进行相加两个数组,其和的长度为两个加数中最大的加1,再考虑进位处理,遇到了n就向高位进位,最后再去除前导零,逆序输出即可。

参考代码:

#include<bits/stdc++.h>
using namespace std;
int n,x[2112],y[2112],z[2112];
string a,b;
int main() {
    cin>>n>>a>>b;
    x[0]=a.size(),y[0]=b.size();
    z[0]=max(x[0],y[0])+1;
    for(int i=0,j=x[0]; i<x[0]; i++,j--)
        if(a[i]>='A') x[j]=a[i]-'A'+10;
        else x[j]=a[i]-'0';
    for(int i=0,j=y[0]; i<y[0]; i++,j--)
        if(b[i]>='A') y[j]=b[i]-'A'+10;
        else y[j]=b[i]-'0';
    for(int i=1; i<=z[0]; i++) {
        z[i]+=x[i]+y[i];
        if(z[i]>=n) {
            z[i+1]+=z[i]/n;
            z[i]%=n;
        }
    }
    while(z[0]&&z[z[0]]==0)z[0]--;
    for(int i=z[0]; i>=1; i--) {
        if(z[i]>=10)cout<<char('A'+z[i]-10);
        else cout<<z[i];
    }
    return 0;
}

D:物品分组

知识点:二分

思路:在最小值(物品价值最小值)和最大值(所有物品价值之和)之间进行二分搜索,检查是否存在一种分组方式(检查在不超过中间值m的数量是否能够分组数),使得所有子数组的和不超过当前中间值,若可以分出k组,那么统计答案,再将最大值放小,否则将最小值放大。

代码:

#include<bits/stdc++.h>
using namespace std;
int n,a[1001],k,l=INT_MAX,m,r,ans;
bool check(int m) {
    int s=0,g=1;
    for(int i=1; i<=n; i++) {
        if(m<a[i]) return 0;
        if(s+a[i]<=m) {
            s+=a[i];
        } else {
            g++;
            s=a[i];
        }
    }
    return g<=k;//g<=k说明组数可能不够,也就意味着m可以再调大
}
int main() {
    cin>>n;
    for(int i=1; i<=n; i++) {
        cin>>a[i];
        l=min(l,a[i]);
        r+=a[i];
    }
    cin>>k;
    while(l<=r) {
        m=l+(r-l)/2;
        if(check(m)) { //m可以分出k组
            ans=m;
            r=m-1;
        } else {
            l=m+1;
        }
    }
    cout<<ans;
    return 0;
}
Copyright ©图灵之星 2024,转载需注明出处该文件修订时间: 2025-06-21 23:34:31

results matching ""

    No results matching ""