acm专题---dfs+bfs

题目来源:http://hihocoder.com/problemset/problem/1049

#1049 : 后序遍历

时间限制:10000ms
单点时限:1000ms
内存限制:256MB

描述

在参与过了美食节之后,小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 : 连连看

时间限制:10000ms
单点时限:1000ms
内存限制:256MB

描述

小江最喜欢玩的游戏"天下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


*/

  

posted @ 2017-02-10 10:53  simple_wxl  阅读(254)  评论(0编辑  收藏  举报