A. Matching
题意:
将字符串中的“?”替换成数字有多少种方案,要求不含前导0,若字符串含前导0,输出0.
分析:
每一处‘?’有10种可能,在特判一下第一位前导0或者’?‘的情况就能求出方案数。
代码:
#include <iostream>
#include <string>
#include <cmath>
#define endl '\n'
using namespace std;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t;
cin>>t;
while(t--)
{
string s;
cin>>s;
int ans=1;
for(int i=0;i<s.size();i++)
{
if(!i&&s[i]=='?') ans*=9;
else if(s[i]=='?'&&i) ans*=10;
}
if(s[0]=='0') cout<<0<<'\n';
else cout<<ans<<'\n';
}
}
B. Sort the Subarray
题意:
给定一个数组a以及他的部分排序数组b,求可能的最大排序区间使数组a能变成b。保证两数组至少有一处不同。
分析:
两个指针从两端扫过,去除两数组相同元素,得到排序区间,再向两侧扩展保证单调的前提下求出最大区间。
代码2:
#include <iostream>
#include <cstdio>
using namespace std;
const int N=2e5+10;
int a[N],b[N];
bool st[N];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
for(int i=1;i<=n;i++) scanf("%d",&b[i]);
for(int i=1;i<=n;i++)
{
if(a[i]==b[i]) st[i]=true;
else st[i]=false;
}
int maxn=0;
int s=0,e=0;
//cout<<e<<endl;
for(int i=1;i<=n;i++)
{
if(!st[i])
{
int j=i+1;
while(!st[j]&&b[j]>=b[j-1]&&j<=n)
{
j++;
}
if(maxn<j-i)
{
maxn=j-i;
s=i;
e=j-1;
}
i=j-1;
}
}
//cout<<e<<endl;
for(int i=s;i>=1;i--)
{
if(b[i]<=b[s])
{
s=i;
}
else break;
}
for(int i=e;i<=n;i++)
{
//cout<<b[i]<<endl;
if(b[i]>=b[e])
{
e=i;
}
else break;
}
printf("%d %d\n",s,e);
}
}
C. Tear It Apart
题意:
选取字符串中多个任意不相邻的点删除字符,求使字符串中只含一种字符的最小方案数。
分析:
枚举26个字母然后遍历字符串找出每个相同字母之间的最大间隔,最后在所有最大间隔的方案中取最小值,对于最小值,每次可以消去一半字符串,因此求出能够整除2的数量就是最小方案数。
代码:
#include <iostream>
#include <string>
#define endl '\n'
using namespace std;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t;
cin>>t;
while(t--)
{
string s;
cin>>s;
int ans=0x3f3f3f3f;
for(int i=0;i<26;i++)
{
char ch=(char)(i+'a');
int len=0;
int cnt=0;
for(int i=0;i<s.size();i++)
{
if(s[i]==ch)
{
len=max(len,cnt);
cnt=0;
}
else cnt++;
}
len=max(len,cnt);
ans=min(ans,len);
}
int res=0;
while(ans)
{
res++;
ans/=2;
}
cout<<res<<'\n';
}
}