当前位置: 首页 > news >正文

HDU 1429(状压+bfs)

题意:在T-1时间内逃出城堡,途中可能会遇到10种门或钥匙,每种门对应一种钥匙。

思路:

简单的bfs,但是判断一个点能否通过不是简单的判断是否走过,而是判断通过该点时拥有的钥匙的状态是否一致。

所以,判重的check数组要多开一维,表示钥匙的状态。状态表示的思想其实就是用一个数值将每一层的情况给表示出来,而状态压缩是用位运算来简化这种表示方法。所以这里用二进制的10个位分别表示每一种钥匙的状态。


#include <algorithm>
#include <iostream>
#include <string.h>
#include <ctype.h>
#include <cstdio>
#include <queue>
using namespace std;
struct node{
	int x, y, sta, time;
	node(int a, int b, int c, int d):x(a),y(b),sta(c),time(d){}
};
int nt[4][2] = {0, 1, 1, 0, 0, -1, -1, 0};
int n, m, t, sx, sy, ex, ey;
int check[25][25][1<<10];
char map[25][25];
queue<node> q;
int bfs()
{
	int tx, ty, tsta, jc;
	check[sx][sy][0] = 1;
	q.push(node(sx, sy, 0, 0));
	while(!q.empty())
	{
		node tp = q.front();
		q.pop();
		if(tp.time >= t) break;	//剪枝 
		for(int i = 0; i < 4; ++i)
		{
			tx = tp.x + nt[i][0];
			ty = tp.y + nt[i][1];
			if(tx < 0 || tx >= n || ty < 0 || ty >= m) continue;
			if(map[tx][ty] == '*') continue;
			tsta = tp.sta;
			if(islower(map[tx][ty]))
			{
				//如果是钥匙,更改tsta判断拿没拿过 
				tsta = (tp.sta | (1<<(map[tx][ty]-'a')));
			}
			else if(isupper(map[tx][ty]))
			{
				//如果是门,判断拿没拿此门的钥匙 
				jc = (tp.sta & (1<<(map[tx][ty]-'A')));
				if(!jc) continue;
			}
			//如果以tsta状态走过该坐标,continue 
			if(check[tx][ty][tsta]) continue;
			if(map[tx][ty] == '^')
			{
				if(t-tp.time-1 > 0) return tp.time+1;
				return -1;
			}
			check[tx][ty][tsta] = 1;
			q.push(node(tx, ty, tsta, tp.time+1));
		}
	}
	return -1;
}
int main()
{
	while(~scanf("%d %d %d", &n, &m, &t))
	{
		memset(check, 0, sizeof check);
		while(!q.empty()) q.pop();
		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;
			}
		}
		cout << bfs() << endl;
	}
	return 0;
}


看到julyc学长写的代码,知道了放入队列时还可以通过强制转换为结构体进行赋值。


平时我们都这么用:

struct node{
	int x, y;
	node(){} 
	node(int a, int b):x(a), y(b){}
};
q.push(node(tx, ty));

julyc的代码告诉了我也可以这么用:

struct node{
	int x, y;
};
q.push((node){tx, ty});

继续加油~

相关文章:

  • 树莓派系统安装初级教程
  • POJ 2528(线段树+离散化)
  • hadoop问题与解决办法
  • HDU 4725(最短路之建图难点)
  • QDU首届易途杯大赛-kk与cillyb的荣誉之战
  • Visual Studio 有哪些好用的插件?
  • QDU首届易途杯大赛-ycb老师与一道简单的物理题
  • SqlTest(2013-07-10)
  • 蓝桥杯-K倍区间(前缀和) 分巧克力(二分)
  • Linux下MySQL5.6源码安装
  • HDU-1024 Max Sum Plus Plus(DP)
  • C#开发微信门户及应用(27)-公众号模板消息管理
  • CodeForces 628D(数位DP)
  • 多重背包--二进制优化
  • JS高级程序设计2nd部分知识要点2
  • E-HPC支持多队列管理和自动伸缩
  • Facebook AccountKit 接入的坑点
  • IOS评论框不贴底(ios12新bug)
  • Js基础知识(一) - 变量
  • js中的正则表达式入门
  • nodejs调试方法
  • PHP 7 修改了什么呢 -- 2
  • PHP 的 SAPI 是个什么东西
  • SpiderData 2019年2月13日 DApp数据排行榜
  • 互联网大裁员:Java程序员失工作,焉知不能进ali?
  • 机器人定位导航技术 激光SLAM与视觉SLAM谁更胜一筹?
  • 基于Android乐音识别(2)
  • 排序算法学习笔记
  • 终端用户监控:真实用户监控还是模拟监控?
  • Android开发者必备:推荐一款助力开发的开源APP
  • 容器镜像
  • ​io --- 处理流的核心工具​
  • ​LeetCode解法汇总2808. 使循环数组所有元素相等的最少秒数
  • #include<初见C语言之指针(5)>
  • #NOIP 2014#day.2 T1 无限网络发射器选址
  • (33)STM32——485实验笔记
  • (C++17) std算法之执行策略 execution
  • (C语言)fread与fwrite详解
  • (笔试题)分解质因式
  • (附源码)基于SpringBoot和Vue的厨到家服务平台的设计与实现 毕业设计 063133
  • (附源码)计算机毕业设计SSM教师教学质量评价系统
  • (力扣题库)跳跃游戏II(c++)
  • (算法)前K大的和
  • (转)视频码率,帧率和分辨率的联系与区别
  • ***linux下安装xampp,XAMPP目录结构(阿里云安装xampp)
  • .Net Core 中间件验签
  • .net core控制台应用程序初识
  • .NET Framework 服务实现监控可观测性最佳实践
  • .Net高阶异常处理第二篇~~ dump进阶之MiniDumpWriter
  • .NET国产化改造探索(三)、银河麒麟安装.NET 8环境
  • .NET简谈设计模式之(单件模式)
  • .NET企业级应用架构设计系列之开场白
  • .NET微信公众号开发-2.0创建自定义菜单
  • .NET中两种OCR方式对比
  • .pyc文件还原.py文件_Python什么情况下会生成pyc文件?