[codeforces 1379A] Acacius and String 2种匹配形式+难想的反例

Codeforces Round #657 (Div. 2)   参与排名人数8684   错过了难得17:00比赛,可惜

[codeforces 1379A]   Acacius and String   2种匹配形式+难想的反例

总目录详见https://blog.csdn.net/mrcrack/article/details/103564004

在线测评地址https://codeforces.com/contest/1379/problem/A

ProblemLangVerdictTimeMemory
A - Acacius and String GNU C++17Accepted31 ms3900 KB

题目大意:给定一个包含问号的字符串,其中的问号能设置成任意小写字符,问该字符串能否只匹配字符串abacaba一次,若能输出将问号替换后的新字符串,若不能,输出NO.

极难的第一题,一度放弃,一度坚持,最终,还是把它给AC了,没看任何人代码,该题,难在想反例,若如下样例能通过,代码也就基本能AC.

Input:
3
13
abacab?bacaba
11
abacab??aba
12
abacab????caba
Output:
NO
YES
abacabazaba
YES
abacabazzzca

基本思路:有2种匹配形式。

1.纯字母的匹配,这种形式比较简单。

2.有问号参与的匹配,这种形式比较难想。

在编写这种情况过程中,一度绝望,难想的测试数据(本文开始部分已经给出),还是想出了,同一字串可匹配的数量较多,但看到了数据范围,n (7≤n≤50), length of a string s.又回过神来了。

样例模拟如下:

7
abacaba

YES
abacaba

abacaba
abacaba
纯字母匹配形式有1种,如上

7
???????

YES
abacaba

???????
abacaba
有问号参与的匹配形式有1种,如上

11
aba?abacaba

Yes
abazabacaba

aba?abacaba
    abacaba
纯字母匹配形式有1种,如上
aba?abacaba
abacaba
有问号参与的匹配形式有1种,如上

11
abacaba?aba

YES
abacabazaba


abacaba?aba
abacaba
纯字母匹配形式有1种,如上
abacaba?aba
    abacaba
有问号参与的匹配形式有1种,如上


15
asdf???f???qwer

NO

纯字母匹配形式有0种
有问号参与的匹配形式有0种

11
abacabacaba

NO

abacabacaba
abacaba

abacabacaba
    abacaba
纯字母匹配形式有2种,如上

对难点数据解释如下:

13
abacab?bacaba

NO

纯字母匹配形式有0种
abacab?bacaba
abacaba

abacab?bacaba
      abacaba
有问号参与的匹配形式有2种,如上
尝试第一种,将?改成a,发现匹配有2种,如下
abacababacaba
abacaba
      abacaba
尝试第二种,将?改成a,发现匹配有2种,如下
abacababacaba
      abacaba
abacaba


11
abacab??aba

YES
abacabazaba

纯字母匹配形式有0种
abacab??aba
abacaba

abacab??aba
    abacaba
有问号参与的匹配形式有2种,如上
尝试第一种匹配,将第一种匹配中的?改成匹配字母,第一种匹配之外的字母'?'改成字母'z',发现匹配有1种,如下
abacabazaba
abacaba
尝试第二种匹配,将第二种匹配中的?改成匹配字母,第二种匹配之外的字母'?'改成字母'z',发现匹配有2种,如下
abacabacaba
    abacaba
abacaba


12
abacab????caba

YES
abacabazzzca

纯字母匹配形式有0种
abacab????caba
abacaba

abacab????caba
       abacaba
有问号参与的匹配形式有2种
尝试第一种匹配,将第一种匹配中的?改成匹配字母,第一种匹配之外的字母'?'改成字母'z',发现匹配有1种,如下
abacabazzzcaba
abacaba
尝试第二种匹配,将第二种匹配中的?改成匹配字母,第二种匹配之外的字母'?'改成字母'z',发现匹配有1种,如下
abacabzabacaba
       abacaba

AC代码如下:

#include <stdio.h>
#include <string.h>
char a[100],b[20]="abacaba",c[100];
int main(){
	int t,n,m,i,acnt,qcnt,j,q,qk[55],k,flag;
	scanf("%d",&t);
	while(t--){
		acnt=qcnt=0,m=7;
		scanf("%d%s",&n,a);
		for(i=0;i<n-m+1;i++){//首字母开始匹配的位置
			q=0;
			for(j=0;j<m;j++)//尝试匹配
				if(a[i+j]!='?'&&a[i+j]!=b[j])break;
				else if(a[i+j]=='?')q=1;//有问号参与的匹配
			if(j==m){//能匹配成功
				if(q)qcnt++,qk[qcnt]=i;//有问号参与的匹配
				else acnt++;//纯字母的匹配
			}
		}
		if(acnt>1)printf("NO\n");//纯字母的匹配
		else if(acnt==1){//纯字母的匹配
			for(i=0;i<n;i++)
				if(a[i]=='?')a[i]='z';//将所有问号变成z
			printf("YES\n");
			printf("%s\n",a);
		}else if(qcnt>=1){//acnt==0,有问号参与的匹配
			flag=0;
			for(i=0;i<n;i++)
				if(a[i]=='?')a[i]='z';//将所有问号变成z
			c[n]='\0';
			for(i=1;i<=qcnt;i++){//尝试每一种匹配情况
				for(j=0;j<n;j++)c[j]=a[j];
				for(j=qk[i];j<qk[i]+m;j++)c[j]=b[j-qk[i]];//将问号变成匹配的字母
				acnt=0;
				for(k=0;k<n-m+1;k++){//生成新的字串后,检验匹配情况
					for(j=0;j<m;j++)
						if(c[k+j]!=b[j])break;
					if(j==m)acnt++;
				}
				if(acnt==1){flag=1;break;}
			}
			if(flag){//只有一次匹配
				printf("YES\n");
				printf("%s\n",c);
			}else printf("NO\n");
		}else printf("NO\n");
	}
	return 0;
}

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值