题目链接:传送门

题目大意:给你一个图,要从起点走到终点并且要吃够足够的金币才能出去,图上有金币(只能吃一次),

有传送门(用一次消耗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走迷宫)的更多相关文章

  1. C语言动态走迷宫

    曾经用C语言做过的动态走迷宫程序,先分享代码如下: 代码如下: //头文件 #include<stdio.h> #include<windows.h>//Sleep(500)函 ...

  2. sdut 2449走迷宫【最简单的dfs应用】

    走迷宫 Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_ 题目描述 一个由n * m 个格子组成的迷宫,起点是(1, 1), 终点是(n, m) ...

  3. 洛谷P1238 走迷宫

    洛谷1238 走迷宫 题目描述 有一个m*n格的迷宫(表示有m行.n列),其中有可走的也有不可走的,如果用1表示可以走,0表示不可以走,文件读入这m*n个数据和起始点.结束点(起始点和结束点都是用两个 ...

  4. BZOJ 2707: [SDOI2012]走迷宫( tarjan + 高斯消元 )

    数据范围太大不能直接高斯消元, tarjan缩点然后按拓扑逆序对每个强连通分量高斯消元就可以了. E(u) = 1 + Σ E(v) / degree(u) 对拍时发现网上2个程序的INF判断和我不一 ...

  5. NYOJ306 走迷宫(dfs+二分搜索)

    题目描写叙述 http://acm.nyist.net/JudgeOnline/problem.php?pid=306 Dr.Kong设计的机器人卡多非常爱玩.它经常偷偷跑出实验室,在某个游乐场玩之不 ...

  6. Problem A: 走迷宫问题

    Problem A: 走迷宫问题Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 9 Solved: 3[Submit][Status][Web Board] ...

  7. BZOJ 2707: [SDOI2012]走迷宫 [高斯消元 scc缩点]

    2707: [SDOI2012]走迷宫 题意:求s走到t期望步数,\(n \le 10^4\),保证\(|SCC| \le 100\) 求scc缩点,每个scc高斯消元,scc之间直接DP 注意每次清 ...

  8. P1238 走迷宫

    原题链接 https://www.luogu.org/problemnew/show/P1238 为了巩固一下刚学习的广搜,练一下迷宫类型的题 不过这道题我用的深搜..... 看问题,我们就知道这道题 ...

  9. golang 实现广度优先算法(走迷宫)

    maze.go package main import ( "fmt" "os" ) /** * 广度优先算法 */ /** * 从文件中读取数据 */ fun ...

随机推荐

  1. CentOS忘记root密码解决办法

    如果是忘记普通的用户密码,那还好说,用root登录命令行界面,修改即可. 但如果是root的话,那就需要这样修改了.   记住,这几篇文章说的都是对的,只是我复杂了,实际只需要将光标移到最后" ...

  2. pandas数据处理基础——基础加减乘除的运算规则

    上周公司对所有员工封闭培训了一个星期,期间没收手机,基本上博客的更新都停止了,尽管培训时间不长,但还是有些收获,不仅来自于培训讲师的,更多的是发现自己与别人的不足,一个优秀的人不仅仅是自己专业那块的精 ...

  3. 使用DataAdpater自动批量更新DataSet中的数据到数据库

    使用DataAdpater的批量更新,好处是不用写具体的sql脚本,尤其是做web服务这个优势非常吸引人. [WebMethod(Description = "Update服务提供的方法,将 ...

  4. Oauth2.0协议曝漏洞 大量社交网站隐私或遭泄露

    2014年是IT业界不平常的一年,XP停服.IE长老漏洞(秘狐)等等层出不穷,现在,社交网络也爆出惊天漏洞:Oauth2.0协议漏洞 继OpenSSL漏洞后,开源安全软件再曝安全漏洞.新加坡南洋理工大 ...

  5. hbase能否代替mysql

    代志远早年就职网易研究院从事MapReduce与DFS系统的自主研发,后增加支付宝数据平台负责Hadoop与HBase体系的架构设计与二次研发,支付宝流计算与分布式搜索系统的设计和研发,后成为支付宝海 ...

  6. 使用jquery dialog

    网页开发中,弹窗还是很有必要的.本人比较喜欢jquery ui的dialog. 但是jquery dialog中也有一些略显不方便的,如:没有z-index的参数设置,脚部的按钮样式没办法自定义…… ...

  7. twemproxy源码分析2——守护进程的创建

    twemproxy源码中关于守护进程的创建实现得比较标准,先贴出代码来,然后结合一些资料来分析和列举一些实现守护进程的常用方法,不过不得不说twemproxy的实现确实是不错的,注释都写在了代码中,直 ...

  8. Oracle VM VirtualBox虚拟机导出教程

    Oracle VM VirtualBox虚拟机导出教程 | 浏览:583 | 更新:2015-01-31 11:21 1 2 3 4 5 6 7 分步阅读 有时我们需要把Oracle VM Virtu ...

  9. todos Vue

    <div id="todo-list-example"> <input v-model="newTodoText" v-on:keyup.en ...

  10. maven+nexus setting.xml配置(收藏)

    <?xml version="1.0" encoding="UTF-8"?> <settings xmlns="http://mav ...