F.匹配串
题目链接:https://ac.nowcoder.com/acm/contest/9983/F
题目描述:
一个模式串指仅包含小写英文字母和至少一个’#‘的字符串,其中’#‘可以匹配一段任意长度的任意小写字母字符串。
一个匹配串指待匹配的只包含小写字母的字符串。
一个模式串和一个匹配串相匹配当且仅当把模式串里面的’#'全部分别替换成空或一段小写字母字符串后,两个串完全相同。
现在给出\mathit nn个模式串,问有多少不同的匹配串与这些模式串全部相匹配。
如果答案有无穷多个,输出-1。
输入描述:
第一行一个正整数n。
接下来n行每行一个只包含小写字母和’#‘的模式串。
1≤n≤10^6
保证输入模式串的长度总和不超过10^6 且每个模式串至少包含一个’#’。
输出描述:
一行一个整数代表答案。
如果答案有无穷多个,输出-1。
示例1:
输入
2
a#
b#
输出
0
示例2:
输入
2
a#x#c
a#c
输出
-1
解题思路:
输出结果不是0就是无穷(-1)(无穷是指#可以添加任意,即有无穷可以匹配的串)
#可以任意替换,并且每一个模式串都包含#,因此每一个模式串都可以利用#添加东西。
当所有串都有其中一段字符串被两个#夹在中间时,都可以变得一模一样。
只有第一个#之前和最后一个#之后的东西影响结果
以第一个#之前为例,有n个串t1,t2……tn,设tn为其中最长的串,则t1~t n-1都是tn的前缀。
举个栗子🌰:设 tn: abcde# t1: ab# t2:abc# t3: abce#……
代码如下:
#include<iostream>
#include<cstdio>
using namespace std;
char s[1000010],pre[1000010],las[1000010];
int check(){
int len = strlen(s); //字符串s的长度
int lenpre = strlen(pre); //第一个#之前的串长度
int lenlas = strlen(las); //最后一个#之前的串长度
for(int i=0;i<len && s[i]!='#';i++){ //判断第一个#之前
if(i>=lenpre)
pre[i]=s[i];
else{
if(s[i]!=pre[i])
return 0;
}
}
for(int i=len-1,j=0;i>=0 && s[i]!='#';i--,j++){ //判断最后一个#之后
if(j>=lenlas)
las[j]=s[i];
else{
if(s[i]!=las[j])
return 0;
}
}
return 1;
}
int main(){
int n;
cin>>n;
for(int i=1;i<=n;i++){
cin>>s;
if(check()==0){
cout<<"0"<<endl;
return 0;
}
}
cout<<"-1"<<endl;
return 0;
}