↓ 跳过正文
  1. Posts/

BZOJ 1644: [Usaco2007 Oct]Obstacle Course 障碍训练课 (BFS,DP)

·972 字·2 分钟

1644: [Usaco2007 Oct]Obstacle Course 障碍训练课
#

Time Limit: 5 Sec Memory Limit: 64 MB Submit: 451 Solved: 226 [Submit][Status][Discuss]

Description
#

考虑一个 N x N (1 <= N <= 100)的有1个个方格组成的正方形牧场。有些方格是奶牛们不能踏上的,它们被标记为了’x’。例如下图:

. . B x . . x x A . . . . x . . x . . . . . x . .

贝茜发现自己恰好在点A处,她想去B处的盐块舔盐。缓慢而且笨拙的动物,比如奶牛,十分讨厌转弯。尽管如此,当然在必要的时候她们还是会转弯的。对于一个给定的牧场,请你计算从A到B最少的转弯次数。开始的时候,贝茜可以使面对任意一个方向。贝茜知道她一定可以到达。

Input
#

第 1行: 一个整数 N 行

2..N + 1: 行 i+1 有 N 个字符 (’.’, ‘x’, ‘A’, ‘B’),表示每个点的状态。

Output
#

行 1: 一个整数,最少的转弯次数。

Sample Input
#

3 .xA … Bx.

Sample Output
#

2

思路:bfs。我一开始的错误做法是用优先队列,以转弯数为关键字。

但是实际上是错的,因为之后到达同一个点的方法可能有更少的转弯数,但是在做 bfs 的时候,之前访问的节点已经被标记了,所以无法更新成更优的值。

正解是类似 dp 的做法。需要注意不需要 vis 数组标记。

用 dir[x][y][i] 表示从 i 方向到达 x,y 需要的转弯数。

初始 dir[s.x][s.y][0..3] 为 0,其余为 inf

然后更新的时候如果dir[fx][fy][i]=min(dir[x][y][j]+1) 当i!=j

dir[fx][fy][i]=min(dir[x][y][j]) 当i=j

代码实现
  1/* ***********************************************
  2Author :111qqz
  3Created Time :2016年04月10日 星期日 17时00分22秒
  4File Name :code/bzoj/1644.cpp
  5************************************************ */
  6
  7#include <cstdio>
  8#include <cstring>
  9#include <iostream>
 10#include <algorithm>
 11#include <vector>
 12#include <queue>
 13#include <set>
 14#include <map>
 15#include <string>
 16#include <cmath>
 17#include <cstdlib>
 18#include <ctime>
 19#define fst first
 20#define sec second
 21#define lson l,m,rt<<1
 22#define rson m+1,r,rt<<1|1
 23#define ms(a,x) memset(a,x,sizeof(a))
 24typedef long long LL;
 25#define pi pair < int ,int >
 26#define MP make_pair
 27
 28using namespace std;
 29const double eps = 1E-8;
 30const int dx4[4]={1,0,0,-1};
 31const int dy4[4]={0,-1,1,0};
 32const int inf = 0x3f3f3f3f;
 33const int N=105;
 34char maze[N][N];
 35int n;
 36bool vis[N][N];
 37int dir[N][N][5];
 38struct node
 39{
 40    int x,y;
 41
 42
 43    bool ok ()
 44    {
 45	if (x>=0&&x<n&&y>=0&&y<n&&maze[x][y]!='x') return true;
 46	return false;
 47    }
 48
 49    void look()
 50    {
 51	cout<<"x:"<<x<<" y:"<<y<<endl;
 52    }
 53
 54}s,e;
 55
 56void bfs()
 57{
 58    queue<node>q;
 59    q.push(s);
 60
 61    while (!q.empty())
 62    {
 63	node pre = q.front(); q.pop();
 64//	pre.look();
 65	for ( int i = 0 ; i < 4 ; i++)
 66	{
 67	    node nxt;
 68	    nxt.x = pre.x + dx4[i];
 69	    nxt.y = pre.y + dy4[i];
 70    	    if (!nxt.ok()) continue;
 71	    for ( int j = 0 ; j < 4 ; j++)
 72	    {
 73		bool flag = false;
 74		if (i==j&&dir[nxt.x][nxt.y][i]>dir[pre.x][pre.y][j])
 75		{
 76		    dir[nxt.x][nxt.y][i] = dir[pre.x][pre.y][j];
 77		    flag = true;
 78		}
 79		if (i!=j&&dir[nxt.x][nxt.y][i]>dir[pre.x][pre.y][j]+1)
 80		{
 81		    dir[nxt.x][nxt.y][i] = dir[pre.x][pre.y][j] + 1;
 82		    flag = true;
 83		}
 84		if (flag)
 85		{
 86		    q.push(nxt);
 87		}
 88
 89	    }
 90	}
 91    }
 92}
 93int main()
 94{
 95	#ifndef  ONLINE_JUDGE
 96	freopen("code/in.txt","r",stdin);
 97  #endif
 98
 99	scanf("%d",&n);
100	for ( int i = 0 ; i < n ; i++) scanf("%s",maze[i]);
101
102	for ( int i = 0 ; i < n ; i ++)
103	    for ( int j = 0 ; j < n ; j++)
104		{
105		    if (maze[i][j]=='A')
106		    {
107			s.x = i ;
108			s.y = j;
109		    }
110		    if (maze[i][j]=='B')
111		    {
112			e.x = i ;
113			e.y = j ;
114		    }
115		}
116
117	ms(dir,0x3f);
118	for ( int i = 0 ; i < 4 ; i++) dir[s.x][s.y][i] = 0;
119	bfs();
120//	for ( int i = 0 ; i < 4 ; i++) cout<<dir[e.x][e.y][i]<<endl;
121	int ans = inf;
122	for ( int i = 0 ; i < 4 ; i++) ans = min(ans,dir[e.x][e.y][i]);
123	printf("%d\n",ans);
124
125    return 0;
126}

相关文章

BZOJ 1632: [Usaco2007 Feb]Lilypad Pond (BFS,dp)

·1661 字·4 分钟
1632: [Usaco2007 Feb]Lilypad Pond # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 496 Solved: 153 [Submit][Status][Discuss] Description # Farmer John 建造了一个美丽的池塘,用于让他的牛们审美和锻炼。这个长方形的池子被分割成了 M 行和 N 列( 1 ≤ M ≤ 30 ; 1 ≤ N ≤ 30 ) 正方形格子的 。某些格子上有惊人的坚固的莲花,还有一些岩石,其余的只是美丽,纯净,湛蓝的水。 贝茜正在练习芭蕾舞,她从一个莲花跳跃到另一个莲花,当前位于一个莲花。她希望在莲花上一个一个的跳,目标是另一个给定莲花。她能跳既不入水,也不到一个岩石上。 令门外汉惊讶的是,贝茜的每次的跳跃像中国象棋的马一样:横向移动1,纵向移动2,或纵向移动1,横向移动2。贝茜有时可能会有多达8个选择的跳跃。 Farmer John 在观察贝茜的芭蕾舞联系,他意识到有时候贝茜有可能跳不到她想去的目的地,因为路上有些地方没有莲花。于是他想要添加几个莲花使贝茜能够完成任务。一贯节俭的Farmer John想添加最少数量的莲花。当然,莲花不能放在石头上。 请帮助Farmer John确定必须要添加的莲花的最少数量。在添加的莲花最少基础上,算出贝茜从起始点跳到目标点需要的最少的步数。最后,还要算出满足添加的莲花的最少数量时,跳跃最少步数的跳跃路径的条数。

BZOJ 1627: [Usaco2007 Dec]穿越泥地 (BFS)

·1161 字·3 分钟
1627: [Usaco2007 Dec]穿越泥地 # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 624 Solved: 411 [Submit][Status][Discuss] Description # 清早6:00,Farmer John就离开了他的屋子,开始了他的例行工作:为贝茜挤奶。前一天晚上,整个农场刚经受过一场瓢泼大雨的洗礼,于是不难想见,FJ 现在面对的是一大片泥泞的土地。FJ的屋子在平面坐标(0, 0)的位置,贝茜所在的牛棚则位于坐标(X,Y) (-500 <= X <= 500; -500 <= Y <= 500)处。当然咯, FJ也看到了地上的所有N(1 <= N <= 10,000)个泥塘,第i个泥塘的坐标为 (A_i, B_i) (-500 <= A_i <= 500;-500 <= B_i <= 500)。每个泥塘都只占据了它所在的那个格子。 Farmer John自然不愿意弄脏他新买的靴子,但他同时想尽快到达贝茜所在的位置。为了数那些讨厌的泥塘,他已经耽搁了一些时间了。如果Farmer John 只能平行于坐标轴移动,并且只在x、y均为整数的坐标处转弯,那么他从屋子门口出发,最少要走多少路才能到贝茜所在的牛棚呢?你可以认为从FJ的屋子到牛棚总是存在至少一条不经过任何泥塘的路径。

BZOJ1619: [Usaco2008 Nov]Guarding the Farm 保卫牧场 (BFS)

·2178 字·5 分钟
1619: [Usaco2008 Nov]Guarding the Farm 保卫牧场 # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 661 Solved: 292 [Submit][Status][Discuss] Description # The farm has many hills upon which Farmer John would like to place guards to ensure the safety of his valuable milk-cows. He wonders how many guards he will need if he wishes to put one on top of each hill. He has a map supplied as a matrix of integers; the matrix has N (1 < N <= 700) rows and M (1 < M <= 700) columns. Each member of the matrix is an altitude H_ij (0 <= H_ij <= 10,000). Help him determine the number of hilltops on the map. A hilltop is one or more adjacent matrix elements of the same value surrounded exclusively by either the edge of the map or elements with a lower (smaller) altitude. Two different elements are adjacent if the magnitude of difference in their X coordinates is no greater than 1 and the magnitude of differences in their Y coordinates is also no greater than 1.

BZOJ 1618: [Usaco2008 Nov]Buying Hay 购买干草 (完全背包)

·537 字·2 分钟
1618: [Usaco2008 Nov]Buying Hay 购买干草 # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 906 Solved: 456 [Submit][Status][Discuss] Description # 约翰的干草库存已经告罄,他打算为奶牛们采购日(1≤日≤50000)磅干草. 他知道N(1≤N≤100)个干草公司,现在用1到N给它们编号.第i个公司卖的干草包重量为Pi(1≤Pi≤5000)磅,需要的开销为Ci(l≤Ci≤5000)美元.每个干草公司的货源都十分充足,可以卖出无限多的干草包. 帮助约翰找到最小的开销来满足需要,即采购到至少H磅干草. Input # 第1行输入N和日,之后N行每行输入一个Pi和Ci. Output # 最小的开销. Sample Input # 2 15 3 2 5 3

BZOJ 1617: [Usaco2008 Mar]River Crossing渡河问题 (DP)

·1188 字·3 分钟
1617: [Usaco2008 Mar]River Crossing渡河问题 # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 837 Solved: 606 [Submit][Status][Discuss] Description # Farmer John以及他的N(1 <= N <= 2,500)头奶牛打算过一条河,但他们所有的渡河工具,仅仅是一个木筏。 由于奶牛不会划船,在整个渡河过程中,FJ必须始终在木筏上。在这个基础上,木筏上的奶牛数目每增加1,FJ把木筏划到对岸就得花更多的时间。 当FJ一个人坐在木筏上,他把木筏划到对岸需要M(1 <= M <= 1000)分钟。当木筏搭载的奶牛数目从i-1增加到i时,FJ得多花M_i(1 <= M_i <= 1000)分钟才能把木筏划过河(也就是说,船上有1头奶牛时,FJ得花M+M_1分钟渡河;船上有2头奶牛时,时间就变成M+M_1+M_2分钟。后面的依此类推)。那么,FJ最少要花多少时间,才能把所有奶牛带到对岸呢?当然,这个时间得包括FJ一个人把木筏从对岸划回来接下一批的奶牛的时间。