#include<iostream>
#include<cstring>
using namespace std;
char s[100010];
int main()
{
cin>>s;
int N=strlen(s);
char t='a';
int flag=0;
for(int i=0; i<N; i++)
{
//cout<<i<<" si= "<<s[i]<<" t= "<<t<<endl;
if(s[i]<=t)
{
s[i]=t;
t++;
}
else
{
//s[i]='*';
}
if(t=='z'+1)
{
flag=1;
break;
}
}
if(flag==0)
{
cout<<"-1"<<endl;
return 0;
}
for(int i=0; i<N; i++)
{
if(s[i]!='*')
cout<<s[i];
}
cout<<endl;
return 0;
}
点击打开链接
让求一个1和0平衡(数量相等)的最长长度,开始想的就是求前i和,然后双重循环判断是否1的个数等于长度一一半,不出意料的超时了,然后想了些剪枝,还是超。后来看题解,思维题,还是前i和,不过遇1就+1,遇0就-1,把每一个前i和第一次出现的地方记录,找一个相等的前i和的长度,找最长。
#include<iostream>
#include<map>
using namespace std;
const int MAX=100010;
map<int, int>mp;
char s[MAX];
int sum[MAX];
int main()
{
int N;
cin>>N;
cin>>(s+1);
sum[0]=0;
for(int i=1; i<=N; i++)
{
sum[i]=sum[i-1]+((s[i]-'0')*2-1);
//s[i]==1 +1
// 0 -1
}
int mx=0;
mp.clear();
for(int i=1; i<=N; i++)
{
//sum[i]=0 不用标记 标记sum 为第一个
if(sum[i]!=0 && mp[sum[i]]==0)
{
mp[sum[i]]=i;
}
else
{
mx=max(mx, i-mp[sum[i]]);
}
}
cout<<mx<<endl;
return 0;
}
A是根据给的式子,求f(l,,,r)的,这是个异或,自己模拟了下,实在想不到做法,后来看答案,还是要根据异或的性质从里面找出来规律,差距还是有的,自己怎么都想不出思路的地方,人家一会就出来。。剩下的就是区间dp了,不算难,区间dp就那个循环,难在智商上了。
#include<iostream>
using namespace std;
int f[5010][5010];
int ans[5010][5010];
int main()
{
int N, Q;
cin>>N;
for(int i=1; i<=N; i++)
{
cin>>f[i][i];
ans[i][i]=f[i][i];
}
for(int len=1; len<=N; len++)
{
for(int i=1; i+len<=N; i++)
{
int j=i+len;
f[i][j]=f[i][j-1]^f[i+1][j];
ans[i][j]=max(ans[i+1][j], ans[i][j-1]);
ans[i][j]=max(ans[i][j], f[i][j]);
}
}
cin>>Q;
int l, r;
while(Q--)
{
cin>>l>>r;
cout<<ans[l][r]<<endl;
}
return 0;
E题是这套里面最简单的了吧,但是没人做,很疑惑,可能题意不好懂?实在做不出来前面的只能往后找了,看了一会就出来了,就是一遍判断就好了。