zoj 2110+poj1562+uva439+zoj1649+zoj2165

B - Tempter of the Bone

The doggie found a bone in an ancient maze, which fascinated him a lot. However, when he picked it up, the maze began to shake, and the doggie could feel the ground sinking. He realized that the bone was a trap, and he tried desperately to get out of this maze.

The maze was a rectangle with sizes N by M. There was a door in the maze. At the beginning, the door was closed and it would open at the T-th second for a short period of time (less than 1 second). Therefore the doggie had to arrive at the door on exactly the T-th second. In every second, he could move one block to one of the upper, lower, left and right neighboring blocks. Once he entered a block, the ground of this block would start to sink and disappear in the next second. He could not stay at one block for more than one second, nor could he move into a visited block. Can the poor doggie survive? Please help him.


Input

The input consists of multiple test cases. The first line of each test case contains three integers N, M, and T (1 < N, M < 7; 0 < T < 50), which denote the sizes of the maze and the time at which the door will open, respectively. The next N lines give the maze layout, with each line containing M characters. A character is one of the following:

'X': a block of wall, which the doggie cannot enter;
'S': the start point of the doggie;
'D': the Door; or
'.': an empty block.

The input is terminated with three 0's. This test case is not to be processed.


Output

For each test case, print in one line "YES" if the doggie can survive, or "NO" otherwise.


Sample Input

4 4 5
S.X.
..X.
..XD
....
3 4 5
S.X.
..X.
...D
0 0 0


Sample Output


NO
YES

题意:给定时间,问能否从S走到D。

思路:奇偶剪枝,一开始没有看出来,tle了两遍,后来才发现(泪目)

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#define N 100
char map[N][N];
int book[N][N];
int n,m,t,sx,sy,ex,ey,flag;
int k[4][2] = {1,0,0,1,-1,0,0,-1};

void dfs(int x,int y,int time)
{
	int nx,ny;
	//hahaha 奇偶剪枝 !
	if(((int)(fabs(x-ex)+fabs(y-ey)))%2 != (t-time)%2||t < time)//如果剩余步数大于剩余时间或者使用时间大于总时间 
		return ;
	if(map[x][y] == 'D'&&t == time)//如果到达终点并且时间严格相等//on exactly the time//认真审题! 
	{
		flag = 1;
		return ;
	}
	for(int i = 0; i < 4; i ++)
	{
		nx = x + k[i][0];
		ny = y + k[i][1];
		if(nx<0||ny<0||nx>n-1||ny>m-1||book[nx][ny]||map[nx][ny]=='X')
			continue;
		book[nx][ny] = 1;
		dfs(nx,ny,time+1);
		book[nx][ny] = 0;
	}
	return ;
}

int main()
{
	while(scanf("%d%d%d",&n,&m,&t),t!=0||n!=0||m!=0)
	{
		for(int i = 0; i < n; i ++)
		{
			scanf("%s",map[i]);
			for(int j = 0; j < m; j ++)
			{
				if(map[i][j] == 'S')
				{
					sx = i;
					sy = j;
				}
				if(map[i][j] == 'D')
				{
					ex = i;
					ey = j;
				}
			}
		}	
		memset(book,0,sizeof(book));
		flag = 0;
		book[sx][sy] = 1;
		if((fabs(sx-ex)+fabs(sy-ey))> t)//如果终点到起点的距离大于总时间
		{
			printf("NO\n");
			continue;
		}
		dfs(sx,sy,0);
		if(!flag)//无法到达终点 
			printf("NO\n");
		else
			printf("YES\n");
	}
	return 0;
}

C - Oil Deposits

The GeoSurvComp geologic survey company is responsible for detecting underground oil deposits. GeoSurvComp works with one large rectangular region of land at a time, and creates a grid that divides the land into numerous square plots. It then analyzes each plot separately, using sensing equipment to determine whether or not the plot contains oil. A plot containing oil is called a pocket. If two pockets are adjacent, then they are part of the same oil deposit. Oil deposits can be quite large and may contain numerous pockets. Your job is to determine how many different oil deposits are contained in a grid.
Input
The input contains one or more grids. Each grid begins with a line containing m and n, the number of rows and columns in the grid, separated by a single space. If m = 0 it signals the end of the input; otherwise 1 <= m <= 100 and 1 <= n <= 100. Following this are m lines of n characters each (not counting the end-of-line characters). Each character corresponds to one plot, and is either `*', representing the absence of oil, or `@', representing an oil pocket.

Output
are adjacent horizontally, vertically, or diagonally. An oil deposit will not contain more than 100 pockets.
Sample Input
1 1
*
3 5
*@*@*
**@**
*@*@*
1 8
@@****@*
5 5 
****@
*@@*@
*@**@
@@@*@
@@**@
0 0
Sample Output
0
1
2
2
题意:判断独立且连通的@有多少个,单独的一个@也算上。

思路:dfs,遍历独立@集的同时全部标记为*.

#include<stdio.h>
#include<string.h>
#define N 100
char map[N+10][N+10];
int n,m;
void dfs(int x,int y)
{
	int k[8][2] = {0,1,0,-1,1,0,-1,0,-1,1,1,1,1,-1,-1,-1};
	for(int i = 0; i < 8; i ++)
	{
		int nx = x + k[i][0];
		int ny = y + k[i][1];
		if(nx < 0||ny < 0||nx > m-1||ny > n-1||map[nx][ny] == '*')
			continue;
		map[nx][ny] = '*';
		dfs(nx,ny);
	}
	return;
}
int main()
{
	int count;
	while(scanf("%d%d",&m,&n),m!=0)
	{
		count  = 0;
		for(int i = 0; i < m; i ++)
			scanf("%s",map[i]);
		for(int i = 0; i < m; i ++)
			for(int j = 0; j < n; j ++)
				if(map[i][j] == '@')
				{
					map[i][j] = '*';
					dfs(i,j);
					count ++;
				}
		printf("%d\n",count);
	}
	return 0;
} 

F - Knight Moves

题意:给定起点和终点的纵坐标、横坐标,按照马走日的走法,问从起点到终点的最小步数(8*8的矩阵)

思路:bfs跑一遍就好了

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<queue>
using namespace std;
#define N 10
int book[N][N],sx,sy,ex,ey,step;
struct node{
	int x,y,step;
};

void bfs()
{
	queue<node>q;
	struct node now1,start,now2;
	int k[8][2] = {-2,-1,-2,1,-1,2,1,2,2,1,2,-1,1,-2,-1,-2};//马走日坐标 
	int nx,ny;
	start.step = 0;
	start.x = sx;
	start.y = sy;
	q.push(start);
	book[sx][sy] = 1;
	while(!q.empty())
	{
		now1 = q.front();
		q.pop();
		if(now1.x == ex&&now1.y == ey)
		{
			step = now1.step ;
			return;
		}
		for(int i = 0; i < 8; i ++)
		{
			nx = now1.x + k[i][0];
			ny = now1.y + k[i][1];
			if(nx < 1||ny < 1||nx > 8||ny > 8||book[nx][ny])
				continue;
			now2.x = nx;
			now2.y = ny;
			now2.step = now1.step + 1;
			book[nx][ny] = 1;
			if(now2.x == ex&&now2.y == ey)
			{
				step = now2.step ;
				return;
			}
			q.push(now2);
		}
	}
	return ;
}

int main()
{
	char s[N],e[N];
	while(scanf("%s%s",s,e)!=EOF)
	{
		memset(book,0,sizeof(book));
		sx = s[1]-'0';
		sy = s[0]-'a'+1;
		ex = e[1]-'0';
		ey = e[0]-'a'+1;
		//printf("sx=%d sy=%d ex=%d ey=%d\n",sx,sy,ex,ey); 
		bfs();
		printf("To get from %s to %s takes %d knight moves.\n",s,e,step);
	}
	return 0;
}

G - Rescue

Angel was caught by the MOLIGPY! He was put in prison by Moligpy. The prison is described as a N * M (N, M <= 200) matrix. There are WALLs, ROADs, and GUARDs in the prison.

Angel's friends want to save Angel. Their task is: approach Angel. We assume that "approach Angel" is to get to the position where Angel stays. When there's a guard in the grid, we must kill him (or her?) to move into the grid. We assume that we moving up, down, right, left takes us 1 unit time, and killing a guard takes 1 unit time, too. And we are strong enough to kill all the guards.

You have to calculate the minimal time to approach Angel. (We can move only UP, DOWN, LEFT and RIGHT, to the neighbor grid within bound, of course.)



Input

First line contains two integers stand for N and M.

Then N lines follows, every line has M characters. "." stands for road, "a" stands for Angel, and "r" stands for each of Angel's friend.

Process to the end of the file.


Output

For each test case, your program should output a single integer, standing for the minimal time needed. If such a number does no exist, you should output a line containing "Poor ANGEL has to stay in the prison all his life."


Sample Input

7 8
#.#####.
#.a#..r.
#..#x...
..#..#.#
#...##..
.#......
........


Sample Output

13

题意:问从a到r的最小时间,每个‘.’需要一秒,每个‘x’需要2秒。

思路:优先队列+bfs的简单应用,我记得貌似r不止一个吧,暑假写过,然后被坑惨了,所以这一次还好啦

//stl库中优先队列的应用(暑假写过,被实力坑过,貌似朋友不止一个?) 
//默认定义:priority_queue<int>q;
//自定义如下: 
#include<iostream>
#include<stdio.h>
#include<queue>
#include<string.h>
using namespace std;
#define N 200
char map[N +10][N +10];
int book[N+10][N+10];
int n,m,step;
int sx,sy,flag;
struct node{
	int time;
	int x,y; 
	friend bool operator < (struct node a,struct node b)
	{
		return a.time > b.time ;//time小的优先级高 
	}//如果a.time>b.time,那么结构体a<b,由于优先队列按照从大到小排,所以b会排在a前面 
};
void bfs()
{
	struct node start,nowq,nowp;
	int k[4][2] = {0,1,0,-1,1,0,-1,0};
	int nx,ny,t;
	start.time = 0;
	start.x = sx;
	start.y = sy;
	priority_queue<node>q;
	q.push(start);
	while(!q.empty())
	{
		nowp = q.top();
	//	printf("x=%d y=%d step=%d\n",nowp.x ,nowp.y ,nowp.time );
		q.pop();
		if(map[nowp.x][nowp.y] == 'r')
		{
			flag = 1;
			step = nowp.time ;
			return;
		}
		for(int i = 0; i < 4; i ++)
		{
			nx = nowp.x + k[i][0];
			ny = nowp.y + k[i][1];
			if(nx < 0||ny < 0||nx > n-1||ny > m-1||book[nx][ny] == 1||map[nx][ny] == '#')
				continue;
			nowq.x = nx;
			nowq.y = ny;
			if(map[nx][ny] == 'x')
				nowq.time = nowp.time + 2;
			else
				nowq.time = nowp.time + 1;
			if(map[nowp.x][nowp.y] == 'r')
			{
				flag = 1;
				step = nowp.time ;
				return;
			}
			book[nx][ny] = 1;
			q.push(nowq);
		}
	}
	return;
}
int main()
{
	while(scanf("%d%d",&n,&m)!=EOF)
	{
		flag = 0;
		for(int i = 0; i < n; i ++)
		{
			scanf("%s",map[i]);
			for(int j = 0; j < m; j ++)
			{
				if(map[i][j] == 'a')
				{
					sx = i;
					sy = j;
				}
			}
		}
		memset(book,0,sizeof(book));
		book[sx][sy] = 1;
		bfs();
		if(!flag)
			printf("Poor ANGEL has to stay in the prison all his life.\n");	
		else
			printf("%d\n",step);
		
	}
	return 0;
 } 

J - Red and Black

There is a rectangular room, covered with square tiles. Each tile is colored either red or black. A man is standing on a black tile. From a tile, he can move to one of four adjacent tiles. But he can't move on red tiles, he can move only on black tiles.

Write a program to count the number of black tiles which he can reach by repeating the moves described above.


Input

The input consists of multiple data sets. A data set starts with a line containing two positive integers W and H; W and H are the numbers of tiles in the x- and y- directions, respectively. W and H are not more than 20.

There are H more lines in the data set, each of which includes W characters. Each character represents the color of a tile as follows.

  • '.' - a black tile
  • '#' - a red tile
  • '@' - a man on a black tile(appears exactly once in a data set)


Output

For each data set, your program should output a line which contains the number of tiles he can reach from the initial tile (including itself).


Sample Input

6 9
....#.
.....#
......
......
......
......
......
#@...#
.#..#.
11 9
.#.........
.#.#######.
.#.#.....#.
.#.#.###.#.
.#.#..@#.#.
.#.#####.#.
.#.......#.
.#########.
...........
11 6
..#..#..#..
..#..#..#..
..#..#..###
..#..#..#@.
..#..#..#..
..#..#..#..
7 7
..#.#..
..#.#..
###.###
...@...
###.###
..#.#..
..#.#..
0 0


Sample Output

45
59
6
13

题意:问从@开始,能到达的'.'有多少个。

思路:BFS一遍,每一个‘.’点计入总数,输出

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<queue>
using namespace std;
#define N 20
#define inf 0x3f3f3f3f
char map[N][N];
int book[N][N];
int n,m,sx,sy,step;

struct node{
	int x,y;
};
void bfs()
{
	queue<node>q;
	struct node now1,now2,start;
	int k[4][2] = {0,1,0,-1,1,0,-1,0};
	int nx,ny;
	step = 1;
	book[sx][sy] = 1;
	start.x = sx;
	start.y = sy;
	q.push(start);
	while(!q.empty())
	{
		now1 = q.front();
		q.pop();
		for(int i = 0; i < 4; i ++)
		{
			nx = now1.x + k[i][0];
			ny = now1.y + k[i][1];
			if(nx < 0||ny < 0||nx > n-1||ny > m-1||book[nx][ny]||map[nx][ny] == '#')
				continue;
			book[nx][ny] = 1;
			now2.x = nx;
			now2.y = ny;
			step ++;
			q.push(now2);
		}
	}
}
int main()
{
	while(scanf("%d%d",&m,&n),m!=0||n!=0)
	{
		for(int i = 0; i < n; i ++)
		{
			scanf("%s",map[i]);
			for(int j = 0; j < m; j ++)
			{
				if(map[i][j] == '@')
				{
					sx = i;
					sy = j;
				}
			}
		}
		memset(book,0,sizeof(book));
		bfs();
		printf("%d\n",step);
	}
	return 0;
}
















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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值