题目:http://codevs.cn/problem/1029/
思路:如果前序位置i处与后序L-i处的字符相等,则该点可能为左根也有可能为右根,而不同则表示此处为左,右分界处。分治求解。
题解:
/* 1029 遍历问题 */
#include <stdio.h>
#define MAXN 28
char preorder[MAXN], postorder[MAXN]; /* 前序,后序字符串 */
int length; /* 字符长度 */
/* 计算中序遍历的可能情况 */
int get_inorder(int x1, int y1, int x2, int y2)
{
int ans = 1;
int i;
int lx, ly, rx, ry;
char lr, rr; /* 左根值,右根值 */
if(x1 >= y1 || x2 >= y2)
{
return 1;
}
/* 测试 - 打印前序,后序遍历字符串 */
/*
for(i = x1; i <= y1; i++)
{
printf("%c", preorder[i]);
}
printf(" <> ");
for(i = x2; i <= y2; i++)
{
printf("%c", postorder[i]);
}
printf("\n");
*/
/***********************************/
/* 如果前后字符相同,则有两种可能 */
for(i = 1; x1 + i <= y1; i++)
{
/* 如果前序,后序字符相等,则有两种可能*/
if(preorder[x1 + i] != postorder[y2 - i])
{
break;
}
ans = ans * 2;
}
/* 记录根节点位置 */
lx = x1 + i;
ry = y2 - i;
lr = preorder[lx]; /* 左子树根字符 */
rr = postorder[ry]; /* 右子树根字符 */
/* 计算前序遍历中右根字符位置 */
ly = y1;
for(i = lx; i <= y1; i++)
{
if(preorder[i] == rr)
{
ly = i;
break;
}
}
/* 计算后序遍历中左根字符位置 */
rx = x2;
for(i = ry; i >= x2; i--)
{
if(postorder[i] == lr)
{
rx = i;
break;
}
}
ans = ans * get_inorder(lx, ly - 1, x2, rx) * get_inorder(ly, y1, rx + 1, ry);
return ans;
}
/* 主函数入口 */
int main()
{
int ans;
/* 打开数据文件 */
FILE *fp;
if(NULL == (fp = fopen("data.txt", "r")))
{
return 1;
}
/***************/
/* 读取前序,后序遍历字符串 */
fscanf(fp, "%s", preorder);
fscanf(fp, "%s", postorder);
/* 计算字符串长度 */
length = 0;
while('\0' != preorder[++length]);
ans = get_inorder(0, length - 1, 0, length - 1);
printf("%d", ans);
/* 关闭数据文件 */
fclose(fp);
/****************/
return 0;
}
思路:前序为根(r)->左(la)->右(rb),后序为左(la)->右(rb)->根(r),如果前序为根(r)->X,后序为根(r)->X,则X可能为左(la),也可能为右(rb),即出现一个分支可能。计算所有字符串中分叉数量ans,则中序遍历有2^ans个可能。
题解:
/* 1029 遍历问题 */
#include <stdio.h>
#define MAXN 28
char preorder[MAXN], postorder[MAXN]; /* 前序,后序字符串 */
int length; /* 字符长度 */
/* 主函数入口 */
int main()
{
int ans;
int i, j;
/* 读取前序,后序遍历字符串 */
scanf("%s", preorder);
scanf("%s", postorder);
/* 计算字符串长度 */
length = 0;
while('\0' != preorder[++length]);
ans = 0;
for(i = 1; i < length; i++)
{
for(j = 0; j < length; j++)
{
if(preorder[i] == postorder[j] && preorder[i - 1] == postorder[j + 1])
{
ans++;
}
}
}
printf("%d", 1<<ans);
return 0;
}