POJ 1035 Spell checker
暴力。
判断是否$correct$的话开一个$map$就可以了。
如果不是correct的,那么就暴力去找单词。$abs\left( {len\left[ i \right] - lent} \right) > = 2$,满足这个条件的那些$s[i]$就不需要检查了,一定不可能。
如果$len[i] = = lent$,直接一位一位统计一下,看看有几位不一样的。
如果$abs(len[i] - lent) = = 1$,偷懒一点的方法可以直接写一个最长公共子序列去计算$s[i]$与$t$的最长公共子序列的长度,虽然跑的就了点,但码量减少了不少。
#pragma comment(linker, "/STACK:1024000000,1024000000") #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<vector> #include<map> #include<set> #include<queue> #include<stack> #include<iostream> using namespace std; typedef long long LL; const double pi=acos(-1.0),eps=1e-8; void File() { freopen("D:\\in.txt","r",stdin); freopen("D:\\out.txt","w",stdout); } char s[10010][20],t[20]; int sz,dp[20][20],len[10010],lent; map<string,bool>f; bool check(int a) { if(len[a]==lent) { int cnt=0; for(int i=0;i<lent;i++) if(s[a][i]!=t[i]) cnt++; if(cnt!=1) return 0; return 1; } memset(dp,0,sizeof dp); for(int i=1;i<=len[a];i++) { for(int j=1;j<=lent;j++) { if(s[a][i-1]==t[j-1]) dp[i][j]=dp[i-1][j-1]+1; else dp[i][j]=max(dp[i][j-1],dp[i-1][j]); } } if(dp[len[a]][lent]==min(len[a],lent)) return 1; return 0; } int main() { sz=0; f.clear(); for(;;) { scanf("%s",s[sz]); if(s[sz][0]=='#') break; len[sz]=strlen(s[sz]); f[s[sz]]=1; sz++; } for(;;) { scanf("%s",t); if(t[0]=='#') break; if(f[t]) { printf("%s is correct\n",t); continue; } else { printf("%s:",t); lent=strlen(t); for(int i=0;i<sz;i++) { if(abs(len[i]-lent)>=2) continue; else { if(check(i)) printf(" %s",s[i]); } } printf("\n"); } } return 0; }