题目来源:http://hihocoder.com/problemset/problem/1049
#1049 : 后序遍历
描述
在参与过了美食节之后,小Hi和小Ho在别的地方又玩耍了一阵子,在这个过程中,小Ho得到了一个非常有意思的玩具——一棵由小球和木棍连接起来的二叉树!
小Ho对这棵二叉树爱不释手,于是给它的每一个节点都标记了一个标号——一个属于A..Z的大写字母,并且没有任意两个节点的标号是一样的。小Hi也瞅准了这个机会,重新巩固了一下小Ho关于二叉树遍历的基础知识~就这样,日子安稳的过了两天。
这天,小Ho正好在求解这棵二叉树的前序、中序和后序遍历的结果,但是却在求出前序遍历和中序遍历之后不小心把二叉树摔到了地上,小球和木棍等零件散落了一地!
小Ho损失了心爱的玩具,正要嚎啕大哭起来,所幸被小Hi发现了,劝说道:“别着急,这不是零件都还在么?拼起来不就是了?”
“可是我忘记了二叉树长什么样子了!”小Ho沮丧道。
“这个简单,你不是刚刚求出了这棵二叉树的前序和中序遍历的结果么,利用这两个信息就可以还原出整棵二叉树来哦!”
“这样么?!!”小Ho止住了泪水,问道:“那要怎么做呢?”
没错!小Ho在这一周遇到的问题便是:给出一棵二叉树的前序和中序遍历的结果,还原这棵二叉树并输出其后序遍历的结果。
提示:分而治之——化大为小,化小为无输入
每个测试点(输入文件)有且仅有一组测试数据。
每组测试数据的第一行为一个由大写英文字母组成的字符串,表示该二叉树的前序遍历的结果。
每组测试数据的第二行为一个由大写英文字母组成的字符串,表示该二叉树的中序遍历的结果。
对于100%的数据,满足二叉树的节点数小于等于26。
输出
对于每组测试数据,输出一个由大写英文字母组成的字符串,表示还原出的二叉树的后序遍历的结果。
-
样例输入
-
AB BA
样例输出
-
BA
#include <iostream>
using namespace std;
#include <vector>
#include<algorithm>
#include<queue>
#include<string>
#include<map>
#include<math.h>
#include<iomanip>
#include<stack>
struct node{
char ch;
node* left,*right;
node(char _ch)
{
ch=_ch;
left=NULL;
right=NULL;
}
};
node* build(string prestr,string midstr,int len)
{
if(len<=0)
{
return NULL;
}
else
{
node* root=new node(prestr[0]);
int idx=0;
for(int i=0;i<len;i++)
{
if(prestr[0]==midstr[i])
{
idx=i;
break;
}
}
root->left=build(prestr.substr(1,idx),midstr.substr(0,idx) , idx);
root->right=build(prestr.substr(idx+1,len-idx-1), midstr.substr(idx+1,len-idx-1), len-idx-1);
cout<<root->ch;
return root;
}
}
int main()
{
string prestr="",midstr="";
cin>>prestr>>midstr;
node* root=build(prestr, midstr,prestr.length());
cout<<endl;
return 0;
}
/*
124536
425136
*/
题目来源:http://hihocoder.com/contest/ntest2015april/problem/3
题目3 : 连连看
描述
小江最喜欢玩的游戏"天下3"最近推出了连连看的小玩法。玩家可以将2个相同图案的牌子连接起来,连接线不多于3根线段(即最多拐2折),就可以成功将这对牌子消除。如示意图所示,红色,黄色和蓝色的消除都是合法的,因为它们分别需要2个,0个和1个折。而黑色的消除是不合法的,因为这对牌至少需要拐3个折才能连接起来。
但是小江并不满足于这个游戏规则,因为他觉得最多只能拐2折这个限制并不合理。好奇的小江想知道的是,给定一个连连看的状态以及某一个牌子,在K折以内可以到达的所有具有相同图案的牌子的数量是多少。
输入
每个输入数据包含多个测试点。
第一行为测试点的个数S <= 20。之后是S个测试点的数据。
每个测试点的第一行为1 <= N <= 200, 1 <= M <= 200,表示连连看的大小。接下来的N行,每一行有M个整数,表示连连看该行的状态,如果为0,则表示该格为空,否则代表一种图案的牌子。
然后是三个整数X <= N, Y <= M,0 <= K <= 10000,表示查询(X, Y)这个牌子在K折以内能消除的所有相同牌子总数。其中连连看左上角的格子坐标为(1, 1),右下角为(N, M)。保证查询的格子是有图案的。
输出
对于每个测试点,输出对应的能消除的所有牌子总数。
提示
样例第一个例子,第(1, 1), (2, 3)和(2, 5)为3个可以在3折内被消除的相同牌子。
-
样例输入
-
3 4 5 1 0 1 0 2 0 0 1 3 1 3 3 1 5 9 6 1 4 8 7 1 3 3 4 5 1 0 1 0 2 0 0 1 3 1 3 3 1 5 9 6 1 4 8 7 1 3 1 2 2 1 10 2 3 1 1 10
样例输出
-
3 2 0
#include<iostream>
#include<algorithm>
#include<vector>
#include<string>
#include<stack>
#include<fstream>
#include<queue>
#include<string.h>
#include<list>
#include<map>
using namespace std;
int mymap[205][205];
bool vis[205][205];
struct point
{
int x;
int y;
int cnt;
int cx;
int cy;
point(int _x,int _y,int _cnt,int _cx,int _cy)
{
x = _x;
y = _y;
cnt = _cnt;
cx = _cx;
cy = _cy;
};
};
int m, n;
bool isok(int newx, int newy,int value)
{
if (newx >= 0 && newy >= 0 && newx <= m+1&&newy <= n+1 && (mymap[newx][newy] == -1 || mymap[newx][newy] == 0 || mymap[newx][newy] == value))
{
return true;
}
else
{
return false;
}
}
int bfs(int start, int end, int k)
{
int a[4][2] = { { 0, -1 }, { 0, 1 }, { -1, 0 }, { 1, 0 } };//左右上下
int cntans = 0;
queue<point> que;
int value = mymap[start][end];
for (int i = 0; i < 4; i++)
{
int newx = start + a[i][0];
int newy = end + a[i][1];
if (isok(newx, newy,value))
{
que.push(point(newx,newy,0,a[i][0],a[i][1]));
}
}
vis[start][end] = true;
while (!que.empty())
{
point top = que.front();
que.pop();
vis[top.x][top.y] = true;
if (mymap[top.x][top.y] == value)
{
cntans++;
continue;
}
else
{
for (int i = 0; i < 4; i++)
{
int tmpx = top.x + a[i][0];
int tmpy = top.y + a[i][1];
if (isok(tmpx, tmpy, value)&&vis[tmpx][tmpy]==false)
{
if (!(top.cx == a[i][0] && top.cy == a[i][1]) && top.cnt >= k)
continue;
else if (!(top.cx == a[i][0] && top.cy == a[i][1]))
{
que.push(point(tmpx,tmpy,top.cnt+1,a[i][0],a[i][1]));
}
else
{
que.push(point(tmpx, tmpy, top.cnt, a[i][0], a[i][1]));
}
}
}
}
}
return cntans;
}
int main()
{
int t;
cin >> t;
for (int i = 0; i < t; i++)
{
cin >> m >> n;
memset(vis, false, sizeof(vis));
for (int j = 0; j <= m+1; j++)
{
for (int k = 0; k <= n+1; k++)
mymap[j][k] = -1;
}
for (int j = 1; j <= m; j++)
{
for (int k = 1; k <= n; k++)
{
cin >> mymap[j][k];
}
}
int x, y, k;
cin >> x >> y >> k;
cout << bfs(x, y, k) << endl;
}
}
/*
3
4 5
1 0 1 0 2
0 0 1 3 1
3 3 1 5 9
6 1 4 8 7
1 3 3
4 5
1 0 1 0 2
0 0 1 3 1
3 3 1 5 9
6 1 4 8 7
1 3 1
2 2
1 10
2 3
1 1 10
3
2
0
*/