A题:Beautiful String
解题报告:
#include<bits/stdc++.h>
#define LL long long
#define pii pair<LL,LL>
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
const int maxn=1e6+5;
const int inf=0x3f3f3f3f;
const LL MOD=1e4+7;
char p[maxn];
int main() {
int T;
scanf("%d",&T);
while(T--){
bool flag=false;
scanf("%s",p+1);
for(int i=2;p[i];i++){
if(p[i]==p[i-1]&&p[i]!='?'){
flag=true;break;
}
}
if(flag) printf("-1\n");
else{
p[0]='z';
for(int i=1;p[i];i++){
if(p[i]=='?'){
if(p[i-1]=='a') {
p[i]='b';if(p[i]==p[i+1]) p[i]='c';
}
else if(p[i-1]=='b'){
p[i]='a';if(p[i]==p[i+1]) p[i]='c';
}else {
p[i]='a';if(p[i]==p[i+1]) p[i]='b';
}
}
}
printf("%s\n",p+1);
}
}
return 0;
}
B题:Beautiful Numbers
解题报告:
记录每个数出现的位置
直接 for 循环遍历从 1 到 n ,判断前 i 个数(最小位置与最大位置之差+1)是否等于 i 。
#include<bits/stdc++.h>
#define LL long long
#define pii pair<int,int>
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
const int maxn=1e6+5;
const int inf=0x3f3f3f3f;
const LL MOD=1e4+7;
int p[maxn];
set<int>s;
int main() {
int T,n;
scanf("%d",&T);
while(T--){
int k;
scanf("%d",&n);
for(int i=1,j;i<=n;i++) {
scanf("%d",&j);p[j]=i;
}
for(int i=1;i<=n;i++) {
s.insert(p[i]);
if (s.size() == 1 || s.size() == n)printf("1");
else if ((*s.rbegin() - (*s.begin()) + 1) == i) printf("1");
else printf("0");
}
s.clear();
printf("\n");
}
return 0;
}
C题:Beautiful Regional Contest
解题报告:
很明显 n<5 无解。
考虑 g+s+d 最大值 n/2 同时要满足 p[k] 与 p[k+1] 不等。
因为要求 g<s&&g<d, 所以一旦找到与领位不等的就可以停止往下找(若有解它一定满足)同时将这一区域设为 g,再同样考虑 s 和 d 即可。
#include<bits/stdc++.h>
#define LL long long
#define pii pair<int,int>
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
const int maxn=1e6+5;
const int inf=0x3f3f3f3f;
const LL MOD=1e4+7;
int p[maxn];
int main() {
int T,n;
scanf("%d",&T);
while(T--){
int g=0,s=0,d=0;
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&p[i]);
if(n<5){
printf("0 0 0\n");continue;
}
int k=n/2;
for(int i=k;i>=1;i--){
if(p[i]==p[i+1]) k--;
else break;
}
for(int i=1;i<=k;i++){
if(p[i]!=p[i+1]) {
g=i;
for(int j=i+1;j<=k;j++){
if(p[j]!=p[j+1]&&(j-i)>g){
s=j-i;
if(k-j>i){
d=k-j;
}break;
}
}
break;
}
}
if(g>0&&s>0&&d>0){
printf("%d %d %d\n",g,s,d);
}else{
printf("0 0 0\n");continue;
}
}
return 0;
}
D题:Beautiful Sequence
解题报告:
观察会发现 0只能和 1 相邻(“01”),3只能和2 相邻(“23”),那么我们优先考虑将他们匹配,s1匹配01,s2匹配23。
对于多余的 1 和 2 我们可以再次匹配。
再有多余的0肯定匹配在s1之后,多余的1匹配在s1之前
多余的2匹配在s2之后,对于的3匹配在s2之前,这写最多能匹配一位。
最后判断剩余数为0且s1最后一位于s2第一位绝对值==1。
#include<bits/stdc++.h>
#define LL long long
#define pii pair<int,int>
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
const int maxn=1e6+5;
const int inf=0x3f3f3f3f;
const LL MOD=1e4+7;
int p[maxn];
int main() {
int a,b,c,d;
scanf("%d%d%d%d",&a,&b,&c,&d);
string s1="",s2="";
while(a>0&&b>0){
s1+="01";a--;b--;
}
if(a>0&&(c||d)>0){
printf("NO\n");return 0;
}
while(c>0&&d>0){
s2+="23";c--;d--;
}
if(d>0&&(s1.size()!=0)){
printf("NO\n");return 0;
}
while(b>0&&c>0){
s1+="21";c--;b--;
}
if(a>0)s1=s1+"0",a--;
if(b>0)s1="1"+s1,b--;
if(c>0)s2+="2",c--;
if(d>0)s2="3"+s2,d--;
if(a>0||b>0||c>0||d>0) printf("NO\n");
else{
if(s1.size()>0&&s2.size()>0&&abs(s1[s1.size() - 1] - s2[0]) != 1) {
printf("NO\n");return 0;
}
printf("YES\n");
for(int i=0;i<s1.size();i++) cout<<s1[i]<<' ';
for(int i=0;i<s2.size();i++) cout<<s2[i]<<' ';
}
return 0;
}