| 题目 | 难度 | 知识点 |
|---|---|---|
| A 小苯的V图 | ★ | 签到 |
| B 小苯的数字切割 | ★ | 签到 |
| C 小苯的Z串匹配 | ★ | 递推模拟 |
| D 小苯的最大和 | ★★ | DP |
| E 小苯的数组构造 | ★★ | 贪心,构造 |
| F 小苯的ovo2.0 | ★★ | 暴力,贪心 |
F题不会做,不过看题解有思路暴力写过了,还是太菜了。
小苯的V图
#include<bits/stdc++.h>
using namespace std;
const int N=1e5*5+10;
typedef long long int LL;
LL a[N],n,t;
int main(void)
{
cin>>a[0]>>a[1]>>a[2];
if(a[0]>a[1]&&a[1]<a[2]) puts("YES");
else puts("NO");
return 0;
}
小苯的数字切割
#include<bits/stdc++.h>
using namespace std;
const int N=1e5*5+10;
typedef long long int LL;
LL a[N],n,t;
int main(void)
{
cin>>t;
while(t--){
string s; cin>>s;
int ans=0;
for(int i=0;i<s.size()-1;i++)
{
int sum1=0,sum2=0;
for(int j=0;j<=i;j++) sum1=sum1*10+s[j]-'0';
for(int j=i+1;j<s.size();j++) sum2=sum2*10+s[j]-'0';
ans=max(ans,sum1+sum2);
}
cout<<ans<<'\n';
}
return 0;
}
小苯的Z串匹配
#include<bits/stdc++.h>
using namespace std;
const int N=1e5*5+10;
typedef long long int LL;
LL a[N],n,t;
char s[N];
int main(void)
{
cin>>t;
while(t--)
{
cin>>n;
int cnt=0;
for(int i=0;i<n;i++) cin>>a[i];
for(int i=0;i<n;i++) cin>>s[i];
for(int i=0;i<n;i++){
if(s[i]=='<' && a[i]>=0) a[i]=-1,cnt++;
if(s[i]=='>' && a[i]<=0) a[i]=1,cnt++;
if(s[i]=='Z' &&a[i]*a[i-1]<=0) a[i]=a[i-1],cnt++;
}
cout<<cnt<<'\n';
}
return 0;
}
小苯的最大和
#include<bits/stdc++.h>
using namespace std;
const int N=1e5*5+10;
typedef long long int LL;
LL a[N],f[N],n,t;
int main(void)
{
cin>>t;
while(t--)
{
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
memset(f,-0x3f,sizeof f);
f[0]=0;
for(int i=1;i<=n;i++)
{
f[i]=max(f[i],f[i-1]+a[i]);
if(i-2>=0) f[i]=max(f[i],f[i-2]);
if(i-3>=0) f[i]=max(f[i],f[i-3]);
}
cout<<f[n]<<'\n';
}
return 0;
}
小苯的数组构造
贪心的构造,如果这里可以为1就尽可能的给1,需要注意的是必须给1就给不是必须就尽可能的不给。
因为需要构造的结果不能为0,所以尽可能的把1给需要的。
#include<bits/stdc++.h>
using namespace std;
const int N=1e5*5+10;
typedef long long int LL;
int main(void)
{
LL t; cin>>t;
while(t--)
{
LL n,x,y; cin>>n>>x>>y;
if(n==1)
{
if(x==y){
puts("YES");
cout<<x<<'\n';
}else {
puts("NO");
}
continue;
}
vector<LL>ve1(31,0),ve2(31,0),ans(31,0);
for(LL i=0,j=x;i<31;i++,j/=2)
{
ve1[i]=j%2;
}
for(LL i=0,j=y;i<31;i++,j/=2)
{
ve2[i]=j%2;
}
int flag=1;
for(int i=0;i<31;i++)
{
if(ve1[i]&&ve2[i]==0)
{
ans[i]=n/2*2;
}
if(ve1[i]&&ve2[i])
{
if(n&1) ans[i]=n;
else ans[i]=n-1;
}
if(ve1[i]==0&&ve2[i]){
flag=0;
}
}
vector<int>ve;
if(flag){
for(int i=1;i<=n;i++)
{
LL sum=0;
for(int j=0;j<31;j++)
{
if(ans[j]&&ans[j]>=(n-i+1))
{
sum=sum+(1<<j),ans[j]--;
}
}
if(sum<=0)
{
for(int j=0;j<31;j++)
{
if(ans[j])
{
sum=sum+(1<<j); ans[j]--;
break;
}
}
}
if(sum<=0) flag=0;
ve.push_back(sum);
}
}
if(flag)
{
puts("YES");
for(int i=0;i<n;i++) cout<<ve[i]<<" ";
cout<<'\n';
}
else puts("NO");
}
return 0;
}
小苯的ovo2.0
贪心v都在中间o都在边上最优,故暴力枚举区间即可。
#include<bits/stdc++.h>
using namespace std;
const int N=1e5*2+10;
typedef long long int LL;
LL pre[N],ne[N],t,n;
string s;
LL solve(int l,int r)
{
string ss=s;
for(int i=1;i<=n;i++)
{
if(ss[i]=='?'&&i>=l&&i<=r) ss[i]='v';
if(ss[i]=='?'&&(i<l||i>r)) ss[i]='o';
}
LL sum=0;
for(int i=0;i<=n+1;i++) pre[i]=0,ne[i]=0;
for(int i=1;i<=n;i++)
{
pre[i]=pre[i-1];
if(ss[i]=='o') pre[i]++;
}
for(int i=n;i>=1;i--)
{
ne[i]=ne[i+1];
if(ss[i]=='o') ne[i]++;
}
for(int i=1;i<=n;i++)
{
if(ss[i]=='v') sum+=pre[i-1]*ne[i+1];
}
return sum;
}
int main(void)
{
cin>>t;
while(t--)
{
cin>>s;
n=s.size();
s='0'+s;
LL sum=0;
for(int i=1;i<=n;i++)
for(int j=i;j<=n;j++) {
sum=max(sum,solve(i,j));
}
cout<<sum<<endl;
}
return 0;
}