USACO 5.4.3 Character Recognition

题目大意(转自NOCOW,有缩减):

这个问题需要你写一个程序完成字符识别的任务。

每个完整的字符图案有 20 行,20 位。每个位是“0”或“1”

文件 font.in 包括了27个字符图案的信息,以这样的顺序记录:

_abcdefghijklmn

其中 _ 表示空格字符。每个完整字符长 20 行。输入文件包含一个或多个可能损坏的字符图案。一个字符图案可能以这些方式被损坏。

  • 最多有一行可能被复制了(就接在原来那一行的下面)
  • 最多有一行可能丢失了
  • 有些“0”可能被改成“1”
  • 有些“1”可能被改成“0”

不会有任何一个字符图案既多余了一行并且又丢失了一行。

被复制的那一行中,原来的行和多余的行可能都损坏了,而且损坏的部分可能并不相同。

写一个程序,使用 font.in 提供的字体,在输入文件提供的图象中识别出一个或多个的字符序列。

使用提供的字体图象来识别字符的时候,要找出最佳的多余行或遗漏行,使找出的所有“0”和“1”的变化数量最小。在所有可能的多余行中,只按损坏数据最少的那一行计算。你必须确定和输入序列最接近的字符序列(就是损坏数据最少的那一个)。每个测试数据有唯一的最优解。

 

简单题解(参考NOCOW):

本题暴力模拟应该是可以过的(USACO的传统)。
在暴力模拟的基础上,保存一些信息,可以加快速度。
保存信息1:dif[i][j][k],表示图案第i行与第j个字符第j行的差距。
保存信息2:cost[i][j],表示图案第i行开始的19+j行最小的匹配差距。
进一步,使用动态规划来求最优解。
令f[i]表示匹配到第i行为止可以取得的最小差距。
边界:f[0]=0,f[1~18]=INF。
转移:f[i]=min{f[i-19]+cost[i-18][0],f[i-20]+cost[i-19][1],f[i-21]+cost[i-20][2]}。
记录下取最优时对应的字符,输出即可。
 
我的代码
 1 /*
 2 ID:t-x.h1
 3 LANG:C++
 4 TASK:charrec
 5 */
 6 #include<cstdio>
 7 FILE *ff=fopen("font.in","r"),*fi=fopen("charrec.in","r"),*fo=fopen("charrec.out","w");
 8 const char ch[]="- abcdefghijklmnopqrstuvwxyz";
 9 const int MAXnf=27+9,N=20,MAXn=1200+9,INF=99999999;
10 char font[MAXnf][N][N],line[MAXn][N];
11 int dif[MAXn][MAXnf][N],cost[MAXn][3],from[MAXn][3];
12 int f[MAXn],g[MAXn],ans[99];
13 int main()
14 {
15         int n,i,j,k,t;
16         fscanf(ff,"%*d\n");
17         for(i=1;i<=27;++i)
18                 for(j=1;j<=N;++j,fscanf(ff,"\n"))
19                         for(k=1;k<=N;++k)
20                                 font[i][j][k]=fgetc(ff);
21         fscanf(fi,"%d\n",&n);
22         for(i=1;i<=n;++i,fscanf(fi,"\n"))
23         {
24                 for(j=1;j<=N;++j)
25                         line[i][j]=fgetc(fi);
26                 for(j=1;j<=27;++j)
27                         for(k=1;k<=N;++k)
28                                 for(t=1;t<=N;++t)
29                                         if(line[i][t]!=font[j][k][t])
30                                                 ++dif[i][j][k];
31         }
32         for(i=1;i+18<=n;++i)
33         {
34                 cost[i][0]=cost[i][1]=cost[i][2]=INF;
35                 for(j=1;j<=27;++j)
36                 {
37                         t=0;
38                         for(k=1;k<N;++k)
39                                 t+=dif[i+k-1][j][k];
40                         if(t<cost[i][0])
41                                 cost[i][0]=t,from[i][0]=j;
42                         for(k=19;k;--k)
43                         {
44                                 t-=dif[i+k-1][j][k],t+=dif[i+k-1][j][k+1];
45                                 if(t<cost[i][0])
46                                         cost[i][0]=t,from[i][0]=j;
47                         }
48                 }
49                 if(i+19<=n)
50                         for(j=1;j<=27;++j)
51                         {
52                                 t=0;
53                                 for(k=1;k<=N;++k)
54                                         t+=dif[i+k-1][j][k];
55                                 if(t<cost[i][1])
56                                         cost[i][1]=t,from[i][1]=j;
57                         }
58                 if(i+20<=n)
59                         for(j=1;j<=27;++j)
60                         {
61                                 t=0;
62                                 for(k=1;k<=N;++k)
63                                         t+=dif[i+k-1][j][k];
64                                 if(t<cost[i][2])
65                                         cost[i][2]=t,from[i][2]=j;
66                                 for(k=N;k;--k)
67                                 {
68                                         t-=dif[i+k-1][j][k],t+=dif[i+k][j][k];
69                                         if(t<cost[i][2])
70                                                 cost[i][2]=t,from[i][2]=j;
71                                 }
72                         }
73         }
74         for(i=1;i<=n;++i)
75                 f[i]=INF;
76         for(i=19;i<=n;++i)
77         {
78                 if(f[i-19]+cost[i-18][0]<f[i])
79                         f[i]=f[i-19]+cost[i-18][0],g[i]=19;
80                 if(i>=20 && f[i-20]+cost[i-19][1]<f[i])
81                         f[i]=f[i-20]+cost[i-19][1],g[i]=20;
82                 if(i>=21 && f[i-21]+cost[i-20][2]<f[i])
83                         f[i]=f[i-21]+cost[i-20][2],g[i]=21;
84         }
85         t=0;
86         for(i=n;i;i-=g[i])
87                 ans[++t]=from[i-g[i]+1][g[i]-19];
88         for(i=t;i;--i)
89                 fputc(ch[ans[i]],fo);
90         fputc(10,fo);
91         fclose(fi);
92         fclose(fo);
93         return 0;
94 }

 

posted @ 2012-08-18 12:53  凌云七风  阅读(528)  评论(0编辑  收藏  举报