题目描述:
就是给一系列frame(字母构成的矩形边框,一个frame为一个大写字母组成的边框)。然后给一张图(矩形阵列),该图是fame按照某个次序往上覆盖的结果显示。
解题思路:
回溯。注意的地方比较多,首先是结果图的存储问题,需要记录争取的字母框四条边位置;其次是回溯的思路,从顶层开始找符合条件的frame,直到最底层;最后是字典序输出问题,这个题理论上26个字母最大结果是不够存的,不过这个题的测试数据似乎开1000也就可以了。
几个小错误地方:(1)字符串清空(2)多组输入!
代码:
#include <stdio.h>
#include <stdlib.h>
#define N 31
#define MAX 1000
typedef struct
{
int left,right,top,bottom;
char c;
}LETTER;
LETTER l[27], letter[27];
int f[N],flag[27],count,r,h,w,result[27],g;
char str[N][N],s[MAX][27];
int testFrame(int t)
{
int i,j;
int tt=letter[t].top,b=letter[t].bottom,l=letter[t].left,r=letter[t].right;
i=tt;
for(j=l;j<=r;j++)
if((flag[str[i][j]-'A'] == 0) && (str[i][j] != letter[t].c))
return 0;
i=b;
for(j=l;j<=r;j++)
if((flag[str[i][j]-'A'] == 0) && (str[i][j] != letter[t].c))
return 0;
j=l;
for(i=tt+1;i<b;i++)
if((flag[str[i][j]-'A'] == 0) && (str[i][j] != letter[t].c))
return 0;
j=r;
for(i=tt+1;i<b;i++)
if((flag[str[i][j]-'A'] == 0) && (str[i][j] != letter[t].c))
return 0;
return 1;
}
void try(int num)
{
int i;
if(num>count)
{
for(i=count;i>=1;i--)
s[g][count-i] = letter[result[i]].c;
g++;
}
else
{
for(i=count;i>=1;i--)//从顶层开始找
{
if((0 == flag[letter[i].c-'A'])&&( testFrame(i) == 1))//该点未被检查过且是一个frame
{
flag[letter[i].c-'A'] = 1;
result[r] = i;
r++;
try(num+1);
r--;
flag[letter[i].c-'A'] = 0;
}
}
}
}
int cmp ( const void *a , const void *b )
{
return strcmp((char *)a ,(char *)b);
}
main()
{
int i,j;
while(scanf("%d %d",&h,&w)!=EOF)
{
//input
for(i=0;i<h;i++)
scanf("%s",str[i]);
//遍历
for(i=0;i<26;i++)
f[i] = 0;
for(i=0;i<h;i++)
for(j=0;j<w;j++)
{
if(str[i][j] >='A' && str[i][j]<='Z')
{
if(f[str[i][j]-'A']==0) //未记录过
{
l[str[i][j]-'A'].c = str[i][j];
l[str[i][j]-'A'].left = j;
l[str[i][j]-'A'].right = j;
l[str[i][j]-'A'].top = i;
l[str[i][j]-'A'].bottom = i;
f[str[i][j]-'A'] = 1;
}
else
{
if( j < l[str[i][j]-'A'].left)
l[str[i][j]-'A'].left = j;
if( j > l[str[i][j]-'A'].right)
l[str[i][j]-'A'].right = j;
if( i > l[str[i][j]-'A'].bottom)
l[str[i][j]-'A'].bottom = i;
}
}
}
count = 0;
//数一共几个。并按次序记录。
for(i=0;i<26;i++)
if(f[i]!=0)
{
count ++;
letter[count] = l[i];//复制到letter里。按次序,前count个。
}
for(i=0;i<26;i++)
flag[i] = 0;
r=1;
memset(s,0,sizeof(s));
g=0;
try(1);
qsort(s,g,sizeof(s[0]),cmp);//排序s[],一共g个(0->g-1)
for(i=0;i<g;i++)
printf("%s\n",s[i]);
}
//system("pause");
return 0;
}