NEU710(wanghang走迷宫)
题目链接:传送门
题目大意:给你一个图,要从起点走到终点并且要吃够足够的金币才能出去,图上有金币(只能吃一次),
有传送门(用一次消耗1金币,必须有金币才能使用),问最少需要多少步才能出去。不能出去输出-1
题目思路:搜索+状态压缩技巧
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <stack>
#include <cctype>
#include <queue>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <climits>
#define lson root<<1,l,mid
#define rson root<<1|1,mid+1,r
#define fi first
#define se second
#define ping(x,y) ((x-y)*(x-y))
#define mst(x,y) memset(x,y,sizeof(x))
#define mcp(x,y) memcpy(x,y,sizeof(y))
using namespace std;
#define gamma 0.5772156649015328606065120
#define MOD 1000000007
#define inf 0x3f3f3f3f
#define N 1000010
#define maxn 400005
typedef pair<int,int> PII; int n,m,k,tx,ty; ///tx ty 记录终点位置
char pic[][];
int vis[][][<<|][]; ///1,2维表示位置,第3维代表走到当前位置吃了哪些金币
int dir[][]={{,},{-,},{,},{,-}}; ///第4维代表当前有多少金币
int dx[],dy[],dcnt; ///dcnt记录有多少传送门,前两个数组记录位置
struct Node{
int x,y,v,cnt,fg; ///fg状态压缩表示当前吃了哪些金币
void ini(){ ///v代表当前有多少金币,cnt代表走了几步
v=cnt=fg=;
}
}node,temp;
void bfs(){
queue<Node>q;
q.push(node);
while(!q.empty()){
node=q.front();q.pop();
int x=node.x;int y=node.y;
if(x==tx&&y==ty){
if(node.v>=k){
printf("%d\n",node.cnt);
return;
}
continue;
}
temp=node;
if(pic[x][y]=='P'&&temp.v){ ///走到了有传送门的位置
temp.cnt++; ///并且有路费可以用传送门
temp.v--;
for(int i=;i<dcnt;++i){
if((dx[i]==x&&dy[i]==y))continue;
int xx=dx[i],yy=dy[i];
if(vis[xx][yy][temp.fg][temp.v])continue;
vis[xx][yy][temp.fg][temp.v]=;
temp.x=xx;temp.y=yy;
q.push(temp);
}
}
for(int i=;i<;++i){
temp=node;
temp.cnt++;
int xx=x+dir[i][],yy=y+dir[i][];
if(xx<||xx>n||yy<||yy>m||pic[xx][yy]=='#')continue;
if(isdigit(pic[xx][yy])){ ///走到了有金币的位置
if(temp.fg&(<<(pic[xx][yy]-''))){ ///金币已经吃过了
if(!vis[xx][yy][temp.fg][temp.v]){
vis[xx][yy][temp.fg][temp.v]=;
temp.x=xx;temp.y=yy;
q.push(temp);
}
}
else{ ///金币还没吃过
temp.fg|=(<<(pic[xx][yy]-''));
temp.v++;
if(!vis[xx][yy][temp.fg][temp.v]){
vis[xx][yy][temp.fg][temp.v]=;
temp.x=xx;temp.y=yy;
q.push(temp);
}
}
}
else{
if(!vis[xx][yy][temp.fg][temp.v]){
vis[xx][yy][temp.fg][temp.v]=;
temp.x=xx;temp.y=yy;
q.push(temp);
}
}
}
}
printf("-1\n");
}
int main(){
int i,j,group,Case=;
scanf("%d",&group);
while(group--){
int gold=;dcnt=;///gold是将'C'转换为数字,方便状态压缩
mst(vis,);
scanf("%d%d%d",&n,&m,&k);
node.ini();
for(i=;i<=n;++i){
scanf("%s",pic[i]+);
for(j=;j<=m;++j){
if(pic[i][j]=='C') pic[i][j]=''+gold++;
else if(pic[i][j]=='P'){
dx[dcnt]=i;dy[dcnt++]=j;
vis[i][j][][]=;
}
else if(pic[i][j]=='E'){
tx=i;ty=j;
}
else if(pic[i][j]=='S'){
node.x=i;node.y=j;
}
}
}
bfs();
}
return ;
}
NEU710(wanghang走迷宫)的更多相关文章
- C语言动态走迷宫
曾经用C语言做过的动态走迷宫程序,先分享代码如下: 代码如下: //头文件 #include<stdio.h> #include<windows.h>//Sleep(500)函 ...
- sdut 2449走迷宫【最简单的dfs应用】
走迷宫 Time Limit: 1000ms Memory limit: 65536K 有疑问?点这里^_ 题目描述 一个由n * m 个格子组成的迷宫,起点是(1, 1), 终点是(n, m) ...
- 洛谷P1238 走迷宫
洛谷1238 走迷宫 题目描述 有一个m*n格的迷宫(表示有m行.n列),其中有可走的也有不可走的,如果用1表示可以走,0表示不可以走,文件读入这m*n个数据和起始点.结束点(起始点和结束点都是用两个 ...
- BZOJ 2707: [SDOI2012]走迷宫( tarjan + 高斯消元 )
数据范围太大不能直接高斯消元, tarjan缩点然后按拓扑逆序对每个强连通分量高斯消元就可以了. E(u) = 1 + Σ E(v) / degree(u) 对拍时发现网上2个程序的INF判断和我不一 ...
- NYOJ306 走迷宫(dfs+二分搜索)
题目描写叙述 http://acm.nyist.net/JudgeOnline/problem.php?pid=306 Dr.Kong设计的机器人卡多非常爱玩.它经常偷偷跑出实验室,在某个游乐场玩之不 ...
- Problem A: 走迷宫问题
Problem A: 走迷宫问题Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 9 Solved: 3[Submit][Status][Web Board] ...
- BZOJ 2707: [SDOI2012]走迷宫 [高斯消元 scc缩点]
2707: [SDOI2012]走迷宫 题意:求s走到t期望步数,\(n \le 10^4\),保证\(|SCC| \le 100\) 求scc缩点,每个scc高斯消元,scc之间直接DP 注意每次清 ...
- P1238 走迷宫
原题链接 https://www.luogu.org/problemnew/show/P1238 为了巩固一下刚学习的广搜,练一下迷宫类型的题 不过这道题我用的深搜..... 看问题,我们就知道这道题 ...
- golang 实现广度优先算法(走迷宫)
maze.go package main import ( "fmt" "os" ) /** * 广度优先算法 */ /** * 从文件中读取数据 */ fun ...
随机推荐
- JS遍历数组类型元素
已停供用户不能再次停供,之前没太处理过多维数组的遍历,趁这个机会回顾一下js数组遍历 可以看出rows 获取了两条数据,为二维数组类型 方法 function batchTgWin() { var r ...
- PHP-XML基于流的解析器及其他常用解析器
PHP中有两种主要的XML解析器 1)基于树的解析器.它是把整个文档存储为树的数据结构中,即需要把整个文档都加载到内存中才能工作.所以,当处理大型XML文档时候,性能剧减.SimpleXML和DOM扩 ...
- Struts2简介以及结果集转发
一.分析之前的项目的不足,编写属于自己的框架二.Struts2简介(面试)三.搭建Struts2的开发环境 1.找到所需的jar包:发行包的lib目录中(不同版本需要的最小jar包是不同的,参见不同版 ...
- 使用Openssl创建证书
概述 SSL证书通过在客户端浏览器和Web服务器之间建立一条SSL安全通道(Secure socketlayer(SSL),SSL安全协议主要用来提供对用户和服务器的认证:对传送的数据进行加密和隐藏: ...
- 通过SectionIndexer实现微信通讯录
这里主要参考了使用SectionIndexer实现微信通讯录的效果 在这里做个记录 效果图 页面使用RelativeLayout,主要分为三个部分,match_parent的主listView,右边字 ...
- 堆越界--coredump 在malloc函数里
一,可执行程序分析: objdump -h xxx,可以看到程序内部各个段的内存分布,结果如下(部分): 26 .data 0000016c 0000000000879d20 0 ...
- FTP软件发送"AUTH TLS"提示 无法连接到服务器
响应: 220-FileZilla Server version 0.9.24 beta 响应: 220-written by Tim Kosse (Tim.Kosse@gmx.de) 响应: 220 ...
- 将Cmder添加到系统右键菜单中
1.把 Cmder 加到环境变量 把Cmder.exe存放的目录添加到系统环境变量: 加完之后,Win+r一下输入cmder,即可. 2.添加 cmder 到右键菜单:环境变量添加后,在任意文件夹中即 ...
- linux一条命令添加一个root级别账户并设置密码
内网机器提权添加账户,无回显,设置密码就不好弄,下面就是添加一个root级别的账户并设置密码的命令 ? 1 useradd -p `openssl passwd -1 -salt 'lsof' a ...
- Effective JavaScript Item 37 认识this的隐式指向
本系列作为Effective JavaScript的读书笔记. CSV数据通常都会被某种分隔符进行分隔.所以在实现CSV Reader时,须要支持不同的分隔符.那么,非常自然的一种实现就是将分隔符作为 ...