大致题意:给你一个由数字和“ ?”组成的字符串,“ ?”可以替换成任意一位数(0-9),问这个字符串可以匹配多少个数字,所匹配的数字不能有前置0.
思路:从头遍历字符串,如果第一位为0,则直接输出0;其他情况遇到 “ ?”判断其位置,因为所匹配的数字不能有前置0,所有如果 ‘ ?’在第一位上则结果乘以9,其他位置则结果乘以10。(注意所匹配的字符串不一定要变化而来,给定的字符串如果没有 “ ?”且第一位不为0,则结果为 1,这唯一的结果就是它自己 )。
ac代码:
#include<iostream>
#include<algorithm>
#include<cstring >
using namespace std;
#define ll long long
const int N=2e5+10;
void solve(){
string s;
cin>>s;
int ans=1;
if(s[0]=='0')
{
cout<<0<<endl;
return ;
}
for(int i=0;i<s.size();i++){
if(s[i]=='?'&&i==0) //?在第一位
ans*=9;
else if(s[i]=='?') // ? 不在第一位
ans*=10;
}
cout<<ans<<endl;
}
int main(){
int t;
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>t;
while(t--){
solve();
}
return 0;
}
题意:给定两个数组a,b(a,b不相等);求一个最大区间 [ L,R ],将 数组a这个区间的数从小到大排序,使得a==b。
思路:我们可以通过找b数组中的最大上升子序列(这个最大上升子序列要存在一个位置的元素和a数组不同)即可。
ac代码:
#include<iostream>
#include<algorithm>
#include<cstring >
#include<queue>
using namespace std;
#define ll long long
const int N=2e5+10;
int a[N],b[N];
void solve(){
int n;
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}
for(int i=1;i<=n;i++){
cin>>b[i];
}
int len=0;
int l=0,r=0;
for(int i=1;i<=n;i++){
bool ok=false;
int cnt=0;
int j=i;
while(b[i]<=b[i+1]&&i<n){
if(a[i]!=b[i]) ok=true;
cnt++;
i++;
}
if(cnt>len&&ok){
len=cnt;
l=j;
r=i;
}
}
cout<<l<<" "<<r<<endl;
}
int main(){
int t;
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>t;
while(t--){
solve();
}
return 0;
}
大致题意:
给定一个字符串s,由小写拉丁字母组成。在一次操作中,可以在其中选择几个(一个或多个)位置,所选位置不能彼此相邻。然后从字符串中删除选定位置上的字母。结果部分被连接起来,而不改变它们的顺序。要使得到的 s 中的所有字母一样,最少需要多少次操作。
思路:
我们对于每个字母都进行贪心处理删除,最后再所有字符操作中选择最小的操作数。那怎么进行贪心处理呢?我们要保留的字符会将给定的字符串换成多个部分,对于每个部分,我们都进行一个隔一个的删除处理,则单个部分的处理的次数为它的长度取log2。
举个例子:codeforces 我们选字符o保留 那么它将字符分成 c def rces三个部分,由于各部分是保留字符分隔的所有,每个部分的删除是不会相连影响的。则将o保留的操作数为 rces的长度 4 取 log2.
为什么是 取log2呢?因为我们每部分都一个隔一个的删除,相当于长度每次都除以2,那么删除次数就是长度取 log2.
ac代码:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
#include<set>
using namespace std;
#define ll long long
const int N=2e5+10;
int a[N],b[N];
set<char> st;
int cc[200]; //存删除对应字符的最大长度
void solve(){
st.clear();
string s;
cin>>s;
memset(cc,0x3f,sizeof cc);
for(int i=0;i<s.size();i++){
st.insert(s[i]);
}
for(auto c:st){
int mx=0;
int len=0;
for(int i=0;i<s.size();i++){
if(s[i]==c){
mx=max(mx,len);
len=0;
}
else
len++;
}
if(len) mx=max(len,mx);
cc[c]=mx;
}
int mi=1e9;
for(int i='a';i<='z';i++){
mi=min(mi,cc[i]); //再所有最大里面 选一个最小的
}
int ans=0;
while(mi){
mi/=2;
ans++;
}
cout<<ans<<endl;
}
int main(){
int t;
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>t;
while(t--){
solve();
}
return 0;
}