↓ 跳过正文
  1. Posts/

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确定必须要添加的莲花的最少数量。在添加的莲花最少基础上,算出贝茜从起始点跳到目标点需要的最少的步数。最后,还要算出满足添加的莲花的最少数量时,跳跃最少步数的跳跃路径的条数。

Input
#

第 1 行: 两个整数 M , N

第 2..M + 1 行:第 i + 1 行,第 i + 1 行 有 N 个整数,表示该位置的状态: 0 为水; 1 为莲花; 2 为岩石; 3 为贝茜开始的位置; 4 为贝茜要去的目标位置。

Output
#

第 1 行: 一个整数: 需要添加的最少的莲花数。如果无论如何贝茜也无法跳到,输出 -1。

第 2 行: 一个整数: 在添加的莲花最少基础上,贝茜从起始点跳到目标点需要的最少的步数。如果第1行输出-1,这行不输出。 第 3 行: 一个整数: 添加的莲花的最少数量时,跳跃步数为第2行输出的值的跳跃路径的条数 如果第1行输出-1,这行不输出。

Sample Input
#

4 8 0 0 0 1 0 0 0 0 0 0 0 0 0 2 0 1 0 0 0 0 0 4 0 0 3 0 0 0 0 0 1 0

Sample Output
#

2 6 2

输出说明

至少要添加2朵莲花,放在了’x’的位置。

0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 x 0 0 0 2 0 1 0 0 0 0 0 2 0 1 0 0 0 0 x 4 0 0 0 0 x 0 x 4 0 0 3 0 0 0 0 0 1 0 3 0 0 0 0 0 1 0 贝茜至少要跳 6 步,有以下两种方案

0 0 0 C 0 0 0 0 0 0 0 C 0 0 0 0 0 B 0 0 0 2 0 F 0 0 0 0 0 2 0 F 0 0 0 0 D G 0 0 0 0 B 0 D G 0 0 A 0 0 0 0 0 E 0 A 0 0 0 0 0 E 0

题意:一个 n*m 的 maze,0 是空,1 是荷花,2 是石头,出发地是 3,每次跳象棋的马字步,只能走在荷花上,但是可以在水上添加荷花,问从 3 到 4,在添加荷花数最少的前提下,添加的荷花数是多少,最少的步数是多少,以及在前面两个最少的前提下,有多少种路径。

思路:前两个好搞,最后一个路径数难住我了。没有写过这种,一开始是想在 bfs 或者 dfs 一遍找路径,但是可能不同路径会经过相同的点,所以 vis 的标记会是个问题,回溯呢?反正我是没搞出来。

正解是用到了类似 dp 的思想,具体可以看代码。

以及:一开始我是想添加一些节点的信息到结构体里,但是发现那样写起来会很麻烦。

所以这道题最好再开几个数组存储节点的额外信息。

还有路径数比较多,要记得开 long long

代码实现
  1/* ***********************************************
  2Author :111qqz
  3Created Time :2016年04月06日 星期三 23时04分48秒
  4File Name :code/bzoj/r1632.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 dx8[8]={2,2,-2,-2,1,1,-1,-1};
 33const int dy8[8]={1,-1,1,-1,2,-2,2,-2};
 34const int inf = 0x3f3f3f3f;
 35const int N=50;
 36int maze[N][N];
 37bool vis[N][N];
 38LL lh[N][N],d[N][N],num[N][N];
 39
 40int n ,m;
 41int sx,sy,ex,ey;
 42
 43
 44
 45void bfs()
 46{
 47    queue<int>x,y;
 48    x.push(sx);
 49    y.push(sy);
 50    vis[sx][sy] = true;
 51
 52    while (!x.empty()&&!y.empty())
 53    {
 54	int px = x.front();x.pop();
 55	int py = y.front();y.pop();
 56
 57	for ( int i = 0  ;i  < 8 ; i++)
 58	{
 59	    int nx = px + dx8[i];
 60	    int ny = py + dy8[i];
 61
 62	    if (nx<0||ny<0||nx>=n||ny>=m||maze[nx][ny]==2) continue;
 63	    int tlh = lh[px][py] + (maze[nx][ny]==0);
 64
 65	    if (tlh<lh[nx][ny])
 66	    {
 67		lh[nx][ny] = tlh;
 68		d[nx][ny] = d[px][py]+1;
 69		num[nx][ny] = num[px][py];
 70		if (vis[nx][ny]) continue;
 71		vis[nx][ny] = true;
 72		x.push(nx);
 73		y.push(ny);
 74	    }else if (tlh==lh[nx][ny])
 75	    {
 76		if (d[px][py]+1<d[nx][ny])
 77		{
 78		    d[nx][ny] = d[px][py] + 1;
 79		    num[nx][ny] =num[px][py];
 80		    if (vis[nx][ny]) continue;
 81		    vis[nx][ny] = true;
 82		    x.push(nx);
 83		    y.push(ny);
 84
 85		}else if (d[px][py]+1==d[nx][ny])
 86		{
 87		    num[nx][ny]+=num[px][py];
 88		    if (vis[nx][ny]) continue;
 89		    vis[nx][ny] = true;
 90		    x.push(nx);
 91		    y.push(ny);
 92		}
 93	    }
 94	}
 95
 96	vis[px][py] = false;
 97    }
 98}
 99int main()
100{
101	#ifndef  ONLINE_JUDGE
102	freopen("code/in.txt","r",stdin);
103  #endif
104
105	ios::sync_with_stdio(false);
106	cin>>n>>m;
107	for ( int i = 0  ; i <n ;  i++)
108	    for ( int j =  0 ; j < m;  j++)
109	    {
110		cin>>maze[i][j];
111		lh[i][j]=d[i][j] = inf;
112		if (maze[i][j]==3)
113		{
114		    sx = i;
115		    sy = j;
116		    lh[sx][sy] = 0;
117		    d[sx][sy]=0;
118		    num[sx][sy] = 1;
119		}
120		if (maze[i][j]==4)
121		{
122		    ex = i ;
123		    ey = j ;
124		}
125	    }
126
127	ms(vis,false);
128	bfs();
129
130	if (lh[ex][ey]==inf)
131	    cout<<-1<<endl;
132	else cout<<lh[ex][ey]<<endl<<d[ex][ey]<<endl<<num[ex][ey]<<endl;
133
134  #ifndef ONLINE_JUDGE
135  fclose(stdin);
136  #endif
137    return 0;
138}

相关文章

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一个人把木筏从对岸划回来接下一批的奶牛的时间。