首页 > 其他分享 >hdu 2821

hdu 2821

时间:2023-05-29 22:33:25浏览次数:34  
标签:map hdu int flag num 方块 2821 dir


题意:n*m的格子上有一些方块放在某些格子上,一个格子可能有几个方块,用'a'-'z'来表示方块数量。


初始的时候可以选择任意空地作为Pusher初始点,Pusher选择一个方向,然后向这个方向前进直到遇到有方块的格子,Pusher把这个格子的方块清除一个,并把它向前推一格(向前不能出界),如果前面一格有方块,那么这些方合起来放在这个格子中。Pusher和有方块的格子之间至少要有一个空地才能推动。


思路:这道题数据量比较小,直接dfs即可,不过要注意的是回溯的时候要注意把修改的状态复原,其次就是机器人的行走路径,遇到箱子或者出界才能转弯,然后就是几个限制条件,按照题意很容易处理。。最后就是起始位置不能够有方块,不然WA。。。



#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

int r,c,s,flag;
int dir[4][2] = {{1,0},{-1,0},{0,1},{0,-1}};
char map[25][25],road[1000],d[5] = {"DURL"};

bool check(int x,int y)
{
	if(x < 0 || x >= r || y < 0 || y >= c) return false;
	return true;
}

void dfs(int x,int y,int num)	//表示出发位置为(x,y),已经消灭了num个箱子
{
	if(num >= s)
	{
		road[num] = 0;
		flag = 1;
		return;
	}
	for(int k = 0; k < 4; k++)
	{
		int i = x + dir[k][0];
		int j = y + dir[k][1];
		if(!check(i,j) || map[i][j]) continue;  //下一步就走出界外,或者与箱子之间没有空格
		while(check(i,j) && !map[i][j])
			i += dir[k][0], j += dir[k][1];
		if(!check(i + dir[k][0],j + dir[k][1])) continue;  //到达棋盘边缘,不能推
		int t = map[i][j];
		map[i+dir[k][0]][j+dir[k][1]] += t - 1;
		map[i][j] = 0;
		road[num] = d[k];
		dfs(i,j,num+1);
		if(flag) return;
		map[i+dir[k][0]][j+dir[k][1]] -= t - 1;
		map[i][j] = t;
	}
}

int main()
{
	while(scanf("%d%d",&c,&r)!=EOF)
	{
		s = flag = 0;
		for(int i = 0; i < r; i++)
		{
			getchar();
			scanf("%s",map[i]);
			for(int j = 0; j < c; j++)
			{
				if(map[i][j] == '.') map[i][j] = 0;
				else map[i][j] -= 'a' - 1;
				s += map[i][j];
			}
		}
		for(int i = 0; i < r; i++)
		{
			if(flag) break;
			for(int j = 0; j < c; j++)
			{
				if(map[i][j]) continue;
				dfs(i,j,0);
				if(flag == 1)
				{
					printf("%d\n%d\n",i,j);
					printf("%s\n",road);
					break;
				}
			}
		}
	}
	return 0;
}




标签:map,hdu,int,flag,num,方块,2821,dir
From: https://blog.51cto.com/u_16143128/6374336

相关文章

  • hdu 1534(差分约束)
    题意:安排计划,有4种约束方式,给出你这些时间的n个约束..如果计划是可行的,求出每一件事发生的最早时间..否则输出“impossible”..①.FAFaba要在b完成后完成..②.FASaba要在b开始前完成..③.SASaba要在b开始前开始..④.SAFaba要在b结束前开......
  • hdu 1532(最大流)
    解题思路:这是一道典型的模板题,直接套用EK算法即可。。。我感觉最大流的本质就是能否找到一个从源点到汇点的增广路径,并将其最小的边作为增加值,沿着增广路上的边进行更新。AC:#include<iostream>#include<cstdio>#include<cstring>#include<queue>usingnamespacestd;consti......
  • hdu 5074(简单dp)
    HatsuneMikuTimeLimit:2000/1000MS(Java/Others)    MemoryLimit:262144/262144K(Java/Others)ProblemDescriptionHatsuneMikuisapopularvirtualsinger.ItisverypopularinbothJapanandChina.Basicallyitisacomputersoftwarethata......
  • hdu 3303(线段树+抽屉原理)
    解题思路:这题利用了抽屉原理,即1-M之间的所有数与M+1的模都不相同。那么可以利用它将要查找所有区间分成[1,Y-1],[Y,2*Y-1],[2*Y,3*Y-1].........一直下去,直到所有的区间都被找一遍,然后就是保存最小的模即可。。。这样就肯定要找每个区间的最小的模,实际上这里可以利用线段树去找,只需......
  • hdu 4417(树状数组+离线算法)
    解题思路:这道题要求某区间内比h小的个数,其实这里可以类似于树状数组求逆序数那样。关键是如何转换成树状数组的模型,这才是本题的难点。我们首先分析,如果知道h在该区间的哪个位置,那么剩下的就很好做了。我们还可以发现,如果找到了当前的比h小的所有点(大于的点我们先忽略掉),那么我们就......
  • hdu 3681(bfs+dfs+状态压缩)
    解题思路:这道题属于图上来回走的问题,可以把重复走的过程弱化,即只强调从u->v的结果,中间经过的节点都不考虑。这道题里面'G','F','Y'是重要的节点,其余的点我们是可以忽略的,也就是说,假设从u->v,我们只需要知道最短路径是多少就可以了,至于是怎么走的,中间绕过了多少个'D'都不是我们关心的......
  • hdu 4012(bfs+位压缩)
    思路:每次涂色以后必有一个格子的颜色是最终的颜色,否则这次涂色根本没意义,所以我们把每次涂色后哪些格子成为最终颜色的所有可能都入队,入队的元素是一个struct包含步数和最终颜色已确定的木块集合,这个集合必须用整数表示,所以用到状态压缩,因为最多只有16个格子,所以用16位的二进制来表......
  • hdu 1593(数学)
    往相反的方面跑,但是,最理想的初始位置并不是圆点和圆上的某一点,应该还有更理想的初始逃跑状态.这里有一点需要注意,就是逃跑者极力想达到理想逃跑初态,而追赶者极力阻止逃跑者达到这一状态,所以,理想初态应该是无论追赶者如何阻止,逃跑者仍然可以达到的理想状态.最理想的......
  • hdu 3577(线段树区间更新)
    题意:输入一个t,表示有t组测试数据;         接下来一行,输入两个数,k,m,其中k表示这个辆车最多可以坐这么多人,m表示有m次询问能否上车;         每一次询问,输入两个数a,b,表示该乘客能否在a站台上车,b站台下车,乘车区间为(a,b--),先后次序;         即我每次询......
  • hdu 3172(并查集+hash)
    解题思路:典型的并查集,只是每个人的名字要转换成数字,可以用map,也可以用字典树,我最开始用的字典树结果爆内存了。。爆内存:#include<iostream>#include<cstdio>#include<cstring>usingnamespacestd;constintmaxn=200000;intn,fa[maxn],trie[maxn][52],cnt,id[2000000],nu......