uva 10047 The Monocycle

这道题目消耗了我不少时间,通过这道题目的解答,我对于广度优先搜索的理解更加深刻了,在BFS里面,每一次对于下一步状态的拓展并不是像以前的简单BFS一样仅仅局限于在位置上的更新,而应该扩展到下一步所有可能到达的状态,例如这道题里面状态由四个维度上的值决定:X坐标,Y坐标,方向,颜色,所以应该用一个四维数组来维护BFS的访问矩阵,并且我深刻理解到,每一次状态的拓展的粒度必须要分到最细,因为一开始的时候写的程序里面每一次拓展状态的时候都是发生了位移的,其实这样分解状态的粒度不够细,造成了多次WRONG ANSWER,但是一直找不到原因在哪,后来恍然大悟,每一次的状态变化只能针对一个维度上的状态发生变化,不能够既移动又旋转,每一次要么向前一步,要么原地旋转,不能够把两种状态变化同时放在一次的状态拓展中。

#include <stdio.h>
#include <string.h>
#include <queue>
#include <functional>
#include <algorithm>
using namespace std;

#define		MAX		30
#define		UP		0
#define		DOWN	1
#define		LEFT	2
#define		RIGHT	3

#define		GREEN	0
#define		BLACK	1
#define		RED		2
#define		BLUE	3
#define		WHITE	4

int start_i, start_j;
int end_i, end_j;
char arr[MAX][MAX];
int visited[MAX][MAX][4][5];
int m, n;
int case_count;

char direc[4][10] = {"up", "down", "left", "right"};
char color[5][10] = {"green", "black", "red", "blue", "white"};

struct state
{
	int i;
	int j;
	int direc;
	int color;
};

bool operator < (const struct state &a, const struct state &b)
{
	return visited[a.i][a.j][a.direc][a.color] > visited[b.i][b.j][b.direc][b.color];
}

priority_queue< struct state, vector<struct state>, less<struct state> > q;


bool is_overflow(int i, int j)
{
	if( !(i>=1 && i<=m) )
		return true;

	if( !(j>=1 && j<=n) )
		return true;

	return false;
}
/*
void print_sta(struct state &sta)
{
	printf("(%d,%d,%s,%s)\n", sta.i, sta.j, direc[sta.direc], color[sta.color]);
}
*/

void bfs(int i, int j, int direc, int color)
{
	//while(!q.empty()) q.pop();
	
	priority_queue< struct state, vector<struct state>, less<struct state> > q;

	int min_step;
	struct state sta;
	int cur_i, cur_j, cur_direc, cur_color;
	sta.i = i; sta.j = j; sta.direc = direc; sta.color = color;
	visited[i][j][direc][color] = 1;
	q.push(sta);

	min_step = 0;
	while(!q.empty())
	{
		cur_i = q.top().i;
		cur_j = q.top().j;
		cur_direc = q.top().direc;
		cur_color = q.top().color;
		q.pop();
		
		if(cur_i==end_i && cur_j==end_j && cur_color==GREEN)
		{
			min_step = visited[cur_i][cur_j][cur_direc][cur_color];
			break;
		}


		if(cur_direc == UP)
		{
			//这是前进一步的状态
			if(!is_overflow(cur_i-1,cur_j) && arr[cur_i-1][cur_j]!='#')
			{
				if(visited[cur_i-1][cur_j][UP][(cur_color+1)%5] == 0)
				{
					visited[cur_i-1][cur_j][UP][(cur_color+1)%5] = visited[cur_i][cur_j][cur_direc][cur_color]+1;
					sta.i=cur_i-1; sta.j=cur_j; sta.direc=UP; sta.color=(cur_color+1)%5;
					q.push(sta);
					//print_sta(sta);
				}
			}

			//这是旋转的下一步的状态
			if(visited[cur_i][cur_j][DOWN][cur_color] == 0)
			{
				visited[cur_i][cur_j][DOWN][cur_color] = visited[cur_i][cur_j][cur_direc][cur_color]+2;
				sta.i=cur_i; sta.j=cur_j; sta.direc=DOWN; sta.color=cur_color;
				q.push(sta);
				//print_sta(sta);
			}

			if(visited[cur_i][cur_j][LEFT][cur_color] == 0)
			{
				visited[cur_i][cur_j][LEFT][cur_color] = visited[cur_i][cur_j][cur_direc][cur_color]+1;
				sta.i=cur_i; sta.j=cur_j; sta.direc=LEFT; sta.color=cur_color;
				q.push(sta);
				//print_sta(sta);
			}

			if(visited[cur_i][cur_j][RIGHT][cur_color] == 0)
			{
				visited[cur_i][cur_j][RIGHT][cur_color] = visited[cur_i][cur_j][cur_direc][cur_color]+1;
				sta.i=cur_i; sta.j=cur_j; sta.direc=RIGHT; sta.color=cur_color;
				q.push(sta);
				//print_sta(sta);
			}
		}

		if(cur_direc == DOWN)
		{
			//这是前进一步的状态
			if(!is_overflow(cur_i+1,cur_j) && arr[cur_i+1][cur_j]!='#')
			{
				if(visited[cur_i+1][cur_j][DOWN][(cur_color+1)%5] == 0)
				{
					visited[cur_i+1][cur_j][DOWN][(cur_color+1)%5] = visited[cur_i][cur_j][cur_direc][cur_color]+1;
					sta.i=cur_i+1; sta.j=cur_j; sta.direc=DOWN; sta.color=(cur_color+1)%5;
					q.push(sta);
					//print_sta(sta);
				}
			}

			//这是旋转的下一步的状态
			if(visited[cur_i][cur_j][UP][cur_color] == 0)
			{
				visited[cur_i][cur_j][UP][cur_color] = visited[cur_i][cur_j][cur_direc][cur_color]+2;
				sta.i=cur_i; sta.j=cur_j; sta.direc=UP; sta.color=cur_color;
				q.push(sta);
				//print_sta(sta);
			}

			if(visited[cur_i][cur_j][LEFT][cur_color] == 0)
			{
				visited[cur_i][cur_j][LEFT][cur_color] = visited[cur_i][cur_j][cur_direc][cur_color]+1;
				sta.i=cur_i; sta.j=cur_j; sta.direc=LEFT; sta.color=cur_color;
				q.push(sta);
				//print_sta(sta);
			}

			if(visited[cur_i][cur_j][RIGHT][cur_color] == 0)
			{
				visited[cur_i][cur_j][RIGHT][cur_color] = visited[cur_i][cur_j][cur_direc][cur_color]+1;
				sta.i=cur_i; sta.j=cur_j; sta.direc=RIGHT; sta.color=cur_color;
				q.push(sta);
				//print_sta(sta);
			}
		}

		if(cur_direc == LEFT)
		{
			//这是前进一步的状态
			if(!is_overflow(cur_i,cur_j-1) && arr[cur_i][cur_j-1]!='#')
			{
				if(visited[cur_i][cur_j-1][LEFT][(cur_color+1)%5] == 0)
				{
					visited[cur_i][cur_j-1][LEFT][(cur_color+1)%5] = visited[cur_i][cur_j][cur_direc][cur_color]+1;
					sta.i=cur_i; sta.j=cur_j-1; sta.direc=LEFT; sta.color=(cur_color+1)%5;
					q.push(sta);
					//print_sta(sta);
				}
			}

			//这是旋转的下一步的状态
			if(visited[cur_i][cur_j][RIGHT][cur_color] == 0)
			{
				visited[cur_i][cur_j][RIGHT][cur_color] = visited[cur_i][cur_j][cur_direc][cur_color]+2;
				sta.i=cur_i; sta.j=cur_j; sta.direc=RIGHT; sta.color=cur_color;
				q.push(sta);
				//print_sta(sta);
			}

			if(visited[cur_i][cur_j][UP][cur_color] == 0)
			{
				visited[cur_i][cur_j][UP][cur_color] = visited[cur_i][cur_j][cur_direc][cur_color]+1;
				sta.i=cur_i; sta.j=cur_j; sta.direc=UP; sta.color=cur_color;
				q.push(sta);
				//print_sta(sta);
			}

			if(visited[cur_i][cur_j][DOWN][cur_color] == 0)
			{
				visited[cur_i][cur_j][DOWN][cur_color] = visited[cur_i][cur_j][cur_direc][cur_color]+1;
				sta.i=cur_i; sta.j=cur_j; sta.direc=DOWN; sta.color=cur_color;
				q.push(sta);
				//print_sta(sta);
			}
		}

		if(cur_direc == RIGHT)
		{
			//这是前进一步的状态
			if(!is_overflow(cur_i,cur_j+1) && arr[cur_i][cur_j+1]!='#')
			{
				if(visited[cur_i][cur_j+1][RIGHT][(cur_color+1)%5] == 0)
				{
					visited[cur_i][cur_j+1][RIGHT][(cur_color+1)%5] = visited[cur_i][cur_j][cur_direc][cur_color]+1;
					sta.i=cur_i; sta.j=cur_j+1; sta.direc=RIGHT; sta.color=(cur_color+1)%5;
					q.push(sta);
					//print_sta(sta);
				}
			}

			//这是旋转的下一步的状态
			if(visited[cur_i][cur_j][LEFT][cur_color] == 0)
			{
				visited[cur_i][cur_j][LEFT][cur_color] = visited[cur_i][cur_j][cur_direc][cur_color]+2;
				sta.i=cur_i; sta.j=cur_j; sta.direc=LEFT; sta.color=cur_color;
				q.push(sta);
				//print_sta(sta);
			}

			if(visited[cur_i][cur_j][UP][cur_color] == 0)
			{
				visited[cur_i][cur_j][UP][cur_color] = visited[cur_i][cur_j][cur_direc][cur_color]+1;
				sta.i=cur_i; sta.j=cur_j; sta.direc=UP; sta.color=cur_color;
				q.push(sta);
				//print_sta(sta);
			}

			if(visited[cur_i][cur_j][DOWN][cur_color] == 0)
			{
				visited[cur_i][cur_j][DOWN][cur_color] = visited[cur_i][cur_j][cur_direc][cur_color]+1;
				sta.i=cur_i; sta.j=cur_j; sta.direc=DOWN; sta.color=cur_color;
				q.push(sta);
				//print_sta(sta);
			}
		}

	}


	printf("Case #%d\n", case_count);
	if(min_step == 0)
		printf("destination not reachable\n");
	else
		printf("minimum time = %d sec\n", min_step-1);
}

void func(int m, int n)
{
	::m = m; ::n = n;

	memset((void*)visited[0][0][0], 0, sizeof(int)*MAX*MAX*4*5);
	bfs(start_i, start_j, UP, GREEN);
}


int main(void)
{
	int m, n;
	int i, j;

	//freopen("input.dat", "r", stdin);
	case_count = 0;
	while(1)
	{
		scanf("%d %d", &m, &n);
		getchar();
		if(!m && !n)
			break;

		for(i=1; i<=m; i++)
		{
			for(j=1; j<=n; j++)
			{
				arr[i][j] = getchar();
				if(arr[i][j] == 'S')
				{ start_i = i; start_j = j; }
				if(arr[i][j] == 'T')
				{ end_i = i; end_j = j; }
			}
			getchar();
		}
		case_count ++;
		if(case_count >= 2)
			printf("\n");
		func(m, n);
	}

	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
信息数据从传统到当代,是一直在变革当中,突如其来的互联网让传统的信息管理看到了革命性的曙光,因为传统信息管理从时效性,还是安全性,还是可操作性等各个方面来讲,遇到了互联网时代才发现能补上自古以来的短板,有效的提升管理的效率和业务水平。传统的管理模式,时间越久管理的内容越多,也需要更多的人来对数据进行整理,并且数据的汇总查询方面效率也是极其的低下,并且数据安全方面永远不会保证安全性能。结合数据内容管理的种种缺点,在互联网时代都可以得到有效的补充。结合先进的互联网技术,开发符合需求的软件,让数据内容管理不管是从录入的及时性,查看的及时性还是汇总分析的及时性,都能让正确率达到最高,管理更加的科学和便捷。本次开发的高校科研信息管理系统实现了操作日志管理、字典管理、反馈管理、公告管理、科研成果管理、科研项目管理、通知管理、学术活动管理、学院部门管理、科研人员管理、管理员管理等功能。系统用到了关系型数据库中王者MySql作为系统的数据库,有效的对数据进行安全的存储,有效的备份,对数据可靠性方面得到了保证。并且程序也具备程序需求的所有功能,使得操作性还是安全性都大大提高,让高校科研信息管理系统更能从理念走到现实,确确实实的让人们提升信息处理效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值