USACO 2015 December Contest, Gold Problem 3. Bessie's Dream

After eating too much fruit in Farmer John's kitchen, Bessie the cow is getting some very
strange dreams! In her most recent dream, she is trapped in a maze in the shape
of an N×M grid of tiles (1≤N,M≤1,000). She starts on the
top-left tile and wants to get to the bottom-right tile. When she is standing on
a tile, she can potentially move to the adjacent tiles in any of the four
cardinal directions.

But wait! Each tile has a color, and each color has a different property!
Bessie's head hurts just thinking about it:

  • If a tile is red, then it is impassable.
  • If a tile is pink, then it can be walked on normally.
  • If a tile is orange, then it can be walked on normally, but will make
    Bessie smell like oranges.
  • If a tile is blue, then it contains piranhas that will only let Bessie
    pass if she smells like oranges.
  • If a tile is purple, then Bessie will slide to the next tile in that
    direction (unless she is unable to cross it). If this tile is also a purple
    tile, then Bessie will continue to slide until she lands on a non-purple tile or
    hits an impassable tile. Sliding through a tile counts as a move. Purple
    tiles will also remove Bessie's smell.

(If you're confused about purple tiles, the example will illustrate their use.)

Please help Bessie get from the top-left to the bottom-right in as few moves as
possible.

INPUT FORMAT (file dream.in):

The first line has two integers N

and M, representing the number of rows and
columns of the maze.

The next N

lines have M

integers each, representing the maze:

  • The integer '0' is a red tile
  • The integer '1' is a pink tile
  • The integer '2' is an orange tile
  • The integer '3' is a blue tile
  • The integer '4' is a purple tile

The top-left and bottom-right integers will always be '1'.

OUTPUT FORMAT (file dream.out):

A single integer, representing the minimum number of moves Bessie must use to
cross the maze, or -1 if it is impossible to do so.

SAMPLE INPUT:

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

SAMPLE OUTPUT:

10

In this example, Bessie walks one square down and two squares to the right (and
then slides one more square to the right). She walks one square up, one square
left, and one square down (sliding two more squares down) and finishes by
walking one more square right. This is a total of 10 moves (DRRRULDDDR).

Problem credits: Nathan Pinsker, inspired by the game "Undertale".

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<string>
#include<queue>
using namespace std;
struct p{
	int x, y, s, l;
	friend bool operator <(p a, p b){
		return a.l > b.l;
	}
};
int dx[4] = {0, 1, 0, -1};
int dy[4] = {1, 0, -1, 0};
	int n, m;
priority_queue<p> q;
int v[1005][1005][2]={0}, a[1005][1005];
void check(p t){
	if (t.x == n && t.y == m){
		cout<<t.l;
		exit(0);
	}
}
int main(){
	freopen("dream.in","r",stdin);
	freopen("dream.out","w", stdout);
	cin>>n>>m;
	for (int i = 1; i <= n; i++)
	    for (int j = 1; j <= m; j++)
	        scanf("%d", &a[i][j]);
    p h;
    for (int i = 1; i <= n;i ++) v[i][0][0] = v[i][0][1] = 1;
    for (int j = 1; j <= m; j++) v[0][j][0] = v[0][j][1] = 1;
    h.x = 1;h.y = 1;h.s = h.l = 0; v[1][1][0] = 1;
    q.push(h);
    while (!q.empty()){
    	h = q.top();

	//	cout<<h.x<<' '<<h.y<<"      "<<h.s<<"   "<<h.l<<endl;
    	q.pop();
    	for (int i = 0; i < 4; i++){
	    	p t = h;
	    	t.x += dx[i]; t.y += dy[i]; t.l++;
			if (!a[t.x][t.y] || v[t.x][t.y][t.s]) continue;
			if (a[t.x][t.y] == 1 || (a[t.x][t.y] == 3 && h.s)){
				check(t);
				q.push(t);
				v[t.x][t.y][t.s] = 1;
				continue;
			}
			if (a[t.x][t.y] == 2){
				check(t);
				t.s = 1;
				v[t.x][t.y][t.s] = 1;
				q.push(t);
				continue;
			}
			if (a[t.x][t.y] == 4){
				int x = t.x - h.x;
				int y = t.y - h.y;
				t.s = 0;
				//cout<<h.x<<' '<<h.y<<' '<<t.x<<' '<<t.y<<' ';
				while (t.x+x && t.y+y && t.x+x <= n && t.y+y <= m && a[t.x+x][t.y+y] && a[t.x+x][t.y+y] != 3){
					t.x += x;
					t.y += y;
					t.l++;
					if (a[t.x][t.y] != 4) break;
				}
				//cout<<t.x<<' '<<t.y<<endl;
				check(t);
				if (!v[t.x][t.y][t.s]){
					q.push(t);
					v[t.x][t.y][t.s] = 1;
				}

			}
	    }
    }
    cout<<"-1";
    return 0;
} 
时间: 2024-05-16 18:06:21

USACO 2015 December Contest, Gold Problem 3. Bessie's Dream的相关文章

Looksery Cup 2015 A

http://codeforces.com/contest/549/problem/A 做的实在是太暴力了,嘿嘿 #include <iostream> #include <cstring> using namespace std; char st[55][55]; int main() { int m,n; while(cin>>m>>n) { memset(st,0,sizeof(st)); int sum=0; for(int i=0; i<m;

POJ 3176 Cow Bowling:简单DP

Cow Bowling http://poj.org/problem?id=3176 Time Limit: 1000MS Memory Limit: 65536K Description The cows don't use actual bowling balls when they go bowling. They each take a number (in the range 0..99), though, and line up in a standard bowling-pin-l

(转)The Road to TensorFlow

Stephen Smith's Blog All things Sage 300- The Road to TensorFlow – Part 7: Finally Some Code leave a comment » Introduction Well after a long journey through Linux, Python, Python Libraries, the Stock Market, an Introduction to Neural Networks and tr

给一个素数 求s和t的最大公约数

题目链接:http://codeforces.com/contest/359/problem/C 题意: 给一个素数x,和a1.a2--an,计算这个式子 的时候,化成了 这个形式, 且t等于 xa1+a2+...+an,求s和t的最大公约数 (1≤n≤105, 2≤x≤109) ,结果对1000000007 取模 更多精彩内容:http://www.bianceng.cnhttp://www.bianceng.cn/Programming/sjjg/ 分析: 直接分析s和t,并不能想到如何求g

Codeforces Round #100 / 140A:简单几何

http://codeforces.com/contest/140/problem/A 过大圆圆心作小圆切线即可发现规律,详见代码. 注意判相等一定要用fabs!!! 完整代码: /*30ms,0KB*/ #include<bits/stdc++.h> using namespace std; int main() { int n, R, r; double a; scanf("%d%d%d", &n, &R, &r); if (r > R |

算法题:UVA 11258 String Partition(dp)

Problem F - String Partition John was absurdly busy for preparing a programming contest recently. He wanted to create a ridiculously easy problem for the contest. His problem was not only easy, but also boring: Given a list of non-negative integers,

Codeforces A. Vasya and Socks

题目链接:http://codeforces.com/contest/460/problem/A #include <iostream> using namespace std; int main() { int m,n; cin>>m>>n; int sum; for(sum=1; m>0; sum++) { m--; if(sum % n == 0) m++; } sum--; cout<<sum<<endl; return 0; }

Codeforces 534 A. Exam

题目链接:http://codeforces.com/contest/534/problem/A 题意大意:给出n个学生,编号为1-n,要求学生坐在一排并且相邻的学生编号相差不能为1,求出满足这样要求的最大学生数量并输出方案. 解题思路:除了1,2,3,4以外,其他的都要按照先找奇数,在排偶数.或者先排偶数,再排奇数. #include <iostream> using namespace std; int main() { int m; cin>>m; if(m == 1) {

Codeforces 456 A. Laptops

题目链接:http://codeforces.com/contest/456/problem/A 提示:一共有n个数,而且a[i],b[i]都<=n;所以我们只需要找当a!=b的时候就行了,代码如下: #include <cstdio> #include <iostream> #include <algorithm> using namespace std; int main() { bool ok=0; int m,a,b; cin>>m; for(