ZOJ 1118 N-Credible Mazes(map+并查集)

N-Credible Mazes

Time Limit: 2 Seconds       Memory Limit: 65536 KB

Background

An n-tersection is defined as a location in n-dimensional space, n being a positive integer, having all non-negative integer coordinates. For example, the location (1,2,3) represents an n-tersection in three dimensional space. Two n-tersections are said to be adjacent if they have the same number of dimensions and their coordinates differ by exactly 1 in a single dimension only. For example, (1,2,3) is adjacent to (0,2,3) and (2,2,3) and (1,2,4), but not to (2,3,3) or (3,2,3) or (1,2). An n-teresting space is defined as a collection of paths between adjacent n-tersections.

Finally, an n-credible maze is defined as an n-teresting space combined with two specific n-tersections in that space, one of which is identified as the starting n-tersection and the other as the ending n-tersection.


Input

The input file will consist of the descriptions of one or more n-credible mazes. The first line of the description will specify n, the dimension of the n-teresting space. (For this problem, n will not exceed 10, and all coordinate values will be less than 10.) The next line will contain 2n non-negative integers, the first n of which describe the starting n-tersection, least dimension first, and the next n of which describe the ending n-tersection. Next will be a nonnegative number of lines containing 2n non-negative integers each, identifying paths between adjacent n-tersections in the n-teresting space. The list is terminated by a line containing only the value �C1. Several such maze descriptions may be present in the file. The end of the input is signalled by space dimension of zero. No further data will follow this terminating zero.


Output

For each maze output it��s position in the input; e.g. the first maze is ��Maze #1��, the second is ��Maze #2��, etc. If it is possible to travel through the n-credible maze��s n-teresting space from the starting n-tersection to the ending n-tersection, also output ��can be travelled�� on the same line. If such travel is not possible, output ��cannot be travelled�� instead.


Example

Input


2 
0 0 2 2
0 0 0 1
0 1 0 2
0 2 1 2
1 2 2 2
-1
3
1 1 1 1 2 3
1 1 2 1 1 3
1 1 3 1 2 3
1 1 1 1 1 0
1 1 0 1 0 0
1 0 0 0 0 0
-1
0
Output
Maze #1 can be travelled
Maze #2 cannot be travelled 

Source:  Greater New York 2000


题意:给定起点和终点,再给出多组相邻点,通过已知相邻点构成的路径,能否从起点到达终点。

思路:首先肯定想到先将n维坐标转化为一维(即具体的数),然后判断起点和终点是否在一个集合中(并查集),若在同一集合,显然能到达,否则,不能到达。

实现:怎么转化一维呢?首先想到Hash表映射,但考虑坐标值都是小于10的,可以将数字连一起,构成一个字符串,然后用stl库中的map函数映射即可。具体看代码。


代码:

#include <bits/stdc++.h>
using namespace std;

map<string,int> maps;
int par[200];

int findhead(int number)
{
	if(par[number]==number) return number;
	return par[number] = findhead(par[number]);
		
}

int build(char path[], int &count)//返回字符串对应的数字 
{
	int index;
	if(maps.find(string(path))==maps.end())//新的字符串 
	{
		maps[string(path)] = ++count;
		index = count;
		par[count] = count;//根结点设为自己 
		
	}
	else index = maps[string(path)];//已经映射过的,直接读取 
	return index;
}

int main()
{
	int n;
	int number = 1;
	while(scanf("%d",&n) && n)
	{
		//输入起始点和结束点 
		int i;
		int p;
		char starting[15], ending[15];
		for(i = 0; i<n; i++)
		{
			scanf("%d", &p);
			starting[i] = p+'0';
		}
		starting[n] = '\0';
		for(i = 0; i<n; i++)
		{
			scanf("%d", &p);
			ending[i] = p+'0';
		}
		ending[n] = '\0';
		
        //相邻点的输入 
		int count = 0;
		maps.clear();
		char path[15];//保存坐标的临时数组 
		while(scanf("%d", &p))
		{
			if(p==-1) break;
			int start, end;
			path[0] = p+'0';
			for(i = 1; i<n; i++)
			{
				scanf("%d", &p);
				path[i] = p+'0';
			}
			path[n] = '\0';
			start = build(path, count);//映射成数字 
						
			for(i = 0; i<n; i++)
			{
				scanf("%d", &p);
				path[i] = p+'0';
			}
			path[n] = '\0';
			end = build(path, count);//映射成数字 
			
			int h1 = findhead(start);
			int h2 = findhead(end);
			if(h1!=h2) par[h1] = h2;
		}
		
		int possible = 1;
		if(maps.find(string(starting))==maps.end()//判断起点和终点是否在路径中 
			|| maps.find(string(ending))==maps.end())
			possible = 0;//不在路径中 
		else
		{
			//判断起点和终点是否属于同一集合 
			int start = maps[string(starting)];
			int end = maps[string(ending)];
			int h1 = findhead(start);
			int h2 = findhead(end);
			if(h1!=h2) possible = 0;
		}
		if (possible) printf("Maze #%d can be travelled\n",number++);
		else printf("Maze #%d cannot be travelled\n",number++);
	}
	return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值