charrec.cpp
来自「dd牛的usaco源代码!对学习算法」· C++ 代码 · 共 126 行
CPP
126 行
/*
ID: dd.ener1
PROG: charrec
LANG: C++
*/
#include <cstdio>
#include <cstring>
using namespace std;
const int INF=100000000;
const int maxn=1200;
char dict[27][20][21];
char s[maxn][21];
int diff[maxn][27][20];//diff[i][k][j]表示第i行与第k个字母第j行的差别
int v[maxn][27];//v[i][k]表示把第i行当成第k个字母的第0行时下面的最小差别
int l[maxn][27];//l[i][k]表示v[i][k]最佳值时的行数
int N;
void input(){
freopen("font.in","r",stdin);
scanf("%d\n",&N);
for(int k=0;k<=26;++k)
for(int i=0;i<20;++i)
scanf("%s\n",dict[k][i]);
freopen("charrec.in","r",stdin);
scanf("%d\n",&N);
for(int i=0;i<N;++i)
scanf("%s\n",s[i]);
}
void solve_diff(){
memset(diff,INF,sizeof(diff));
for(int i=0;i<N;++i)
for(int k=0;k<=26;++k)
for(int j=0;j<20;++j){
diff[i][k][j]=0;
for(int l=0;l<20;++l)
diff[i][k][j]+=(s[i][l]!=dict[k][j][l]);
}
for(int k=0;k<=26;++k)
diff[N][k][0]=0;
}
bool update(int& old,int x){
if(old>x){
old=x;
return true;
}
return false;
}
void solve(int I,int K){
v[I][K]=INF;
{
//没有添加和遗漏的情况
int res1=INF;
for(int k=0;k<=26;++k)
update(res1,v[I+20][k]);
for(int j=0;j<20;++j)
res1+=diff[I+j][K][j];
if(update(v[I][K],res1))
l[I][K]=20;
}
{
//遗漏了一行的情况
int res21=INF;
for(int k=0;k<=26;++k)
update(res21,v[I+19][k]);
int res22=INF;
for(int del=0;del<20;++del){
int t=0;
for(int j1=0,j2=0;j1<19;++j1,++j2){
if(j2==del)++j2;
t+=diff[I+j1][K][j2];
}
update(res22,t);
}
if(update(v[I][K],res21+res22))
l[I][K]=19;
}
{
//添加了一行的情况
int res31=INF;
for(int k=0;k<=26;++k)
update(res31,v[I+21][k]);
int res32=INF;
for(int del=0;del<21;++del){
int t=0;
for(int j1=0,j2=0;j1<21;++j1,++j2){
if(j1==del)++j1;
t+=diff[I+j1][K][j2];
}
update(res32,t);
}
if(update(v[I][K],res31+res32))
l[I][K]=21;
}
}
void solve(){
solve_diff();
for(int i=N-1;i>=0;--i)
for(int k=0;k<=26;++k)
solve(i,k);
}
void print(int k){
if(!k)
putchar(' ');
else
putchar('a'-1+k);
}
void output(){
freopen("charrec.out","w",stdout);
for(int I=0;I<N;){
int best=INF,K=-1;
for(int k=0;k<=26;++k)
if(update(best,v[I][k]))
K=k;
print(K);
I+=l[I][K];
}
putchar('\n');
}
int main(){
input();
solve();
output();
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?