目录
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;
}