poj 1229
dp题,神奇的替换:
ONE 匹配一个单词
ZERO_ONE 匹配零个或一个单词
ANY 可以匹配零个或多个单词
这样:
* = ONE, ANY
? = ONE, ZERO_ONE, ZERO_ONE
! = ONE, ONE, ONE, ANY
替换后即可dp。
注意这个例子:
a.b.?
!.c (输出yes)
代码:
#include<iostream> #include<fstream> using namespace std; char c[400][300],c1[400][300]; int n1,n2; char c2[120000]; int n; bool dp[400][400]; void solve(){ int i,j,k; memset(dp,0,sizeof(dp)); dp[0][0]=1; for(i=1;i<=n1;i++) for(j=1;j<=n2;j++) { if(c[i][0]!='*'&&c[i][0]!='?'&&c[i][0]!='!'&&c1[j][0]!='*'&&c1[j][0]!='?'&&c1[j][0]!='!') { if(strcmp(c[i],c1[j])==0) dp[i][j]=dp[i-1][j-1]; else dp[i][j]=0; } if(c[i][0]=='*') dp[i][j]=dp[i][j]||dp[i][j-1]||dp[i-1][j]; if(c[i][0]=='?') dp[i][j]=dp[i][j]||dp[i-1][j-1]; if(c[i][0]=='!') dp[i][j]=dp[i][j]||dp[i-1][j]||dp[i-1][j-1]; if(c1[j][0]=='*') dp[i][j]=dp[i][j]||dp[i][j-1]||dp[i-1][j]; if(c1[j][0]=='?') dp[i][j]=dp[i][j]||dp[i-1][j-1]; if(c1[j][0]=='!') dp[i][j]=dp[i][j]||dp[i-1][j-1]||dp[i][j-1]; } if(dp[n1][n2]) cout<<"YES"<<endl; else cout<<"NO"<<endl; } void read(){ // ifstream cin("in.txt"); int i,j,k; int K; cin>>K; while(K--) { n1=n2=1; memset(c,0,sizeof(c)); memset(c1,0,sizeof(c1)); cin>>c2; k=0; for(i=0;i<strlen(c2);i++) { if(c2[i]=='.') { n1++; k=0; } else { if(c2[i]=='*') { c[n1][0]='?'; n1++; c[n1][0]='*'; } else if(c2[i]=='?') { c[n1][0]='?'; n1++; c[n1][0]='!'; n1++; c[n1][0]='!'; } else if(c2[i]=='!') { c[n1][0]='?'; n1++; c[n1][0]='?'; n1++; c[n1][0]='?'; n1++; c[n1][0]='*'; } else c[n1][k++]=c2[i]; } } cin>>c2; k=0; for(i=0;i<strlen(c2);i++) { if(c2[i]=='.') { n2++; k=0; } else { if(c2[i]=='*') { c1[n2][0]='?'; n2++; c1[n2][0]='*'; } else if(c2[i]=='?') { c1[n2][0]='?'; n2++; c1[n2][0]='!'; n2++; c1[n2][0]='!'; } else if(c2[i]=='!') { c1[n2][0]='?'; n2++; c1[n2][0]='?'; n2++; c1[n2][0]='?'; n2++; c1[n2][0]='*'; } else c1[n2][k++]=c2[i]; } } solve(); } } int main(){ read(); return 0; }