acwing第45届周赛

 

目录

 

1.字符串价值

2.最长连续字符串 

3.最大子矩阵


1.字符串价值

 

题解思路:这题就是个签到题,字符串模拟,直接看代码吧 

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int a1,a2,a3,a4;
    long long ans=0;
    scanf("%d%d%d%d",&a1,&a2,&a3,&a4);
    string s;
    cin>>s;
 
    for(int i=0;i<=s.length();i++)
    {
      if(s[i]=='1')ans+=a1;
        if(s[i]=='2')ans+=a2;
         if(s[i]=='3')ans+=a3;
          if(s[i]=='4')ans+=a4;
    }
    cout<<ans<<endl;
    return 0;
}

2.最长连续字符串 

 

 

题解思路:在比赛的时候我知道这是双指针但还是处理不好具体的细节问题, 不知道要用数组来去重。

 

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

const int N = 500050,M=1000010;
int cnt[M],w[N];
int main()
{
    int n,k,l,r,res=0;
    cin>>n>>k;
    for(int i=1;i<=n;i++)cin>>w[i];
    for(int i=1,j=1,t=0;i<=n;i++)//i和j都只能单调地向后移,动j往后移动就是删除数,i往后移动就是增加数
    {
        if(cnt[w[i]]==0)t++;
        cnt[w[i]]++;
        while(t>k)//不同元素比k要大那么就要删除
        {
            if(cnt[w[j]]==1)t--;
            cnt[w[j]]--;
            j++;
        }
        if(i-j+1>res)
        {
            res=i-j+1;
            l=j,r=i;
        }
        
    }
    cout<<l<<" "<<r<<endl;
    return 0;
}

3.最大子矩阵

 

题解思路:我们要使区间长度的乘积最大,那么相同长度的区间其区间和肯定是越小越好,然后枚举所有可能的区间长度的选法 

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 2010, INF = 1e8;

int n, m, X;
int s1[N], s2[N];//前缀和数组
int a[N], b[N];//用来表示数组里面对应的长度最小和

int main()
{
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; i ++ )
    {
        int x;
        scanf("%d", &x);
        s1[i] = s1[i - 1] + x;
    }

    for (int i = 1; i <= m; i ++ )
    {
        int x;
        scanf("%d", &x);
        s2[i] = s2[i - 1] + x;
    }

    for (int len = 1; len <= n; len ++ )//枚举每个长度下最小和是多少
    {
        a[len] = INF;
        for (int i = 1; i + len - 1 <= n; i ++ )//再枚举左端点
        {
            int j = i + len - 1;//然后先算出来右端点
            a[len] = min(a[len], s1[j] - s1[i - 1]);//从j到i的前缀和
        }
    }

    for (int len = 1; len <= m; len ++ )
    {
        b[len] = INF;
        for (int i = 1; i + len - 1 <= m; i ++ )
        {
            int j = i + len - 1;
            b[len] = min(b[len], s2[j] - s2[i - 1]);
        }
    }

    scanf("%d", &X);

    int res = 0;
    for (int i = 1, j = m; i <= n; i ++ )
    //面积要最大的话那么就让a数组那一段最短即从 1开始枚举,b数组那一段最长从m开始枚举
    {
        while (j && b[j] > X / a[i]) j -- ;//如果乘积大于x的话那么就要j--
        res = max(res, i * j);
    }

    printf("%d\n", res);
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值