7-9The Morning after Halloween uva1601
这题可以用普通bfs来做 也可以用双向bfs来做(先欠着)
有点类似专题训练的一题 不过那题是找钥匙开门 不过都用了状态压缩
题意: n,m(<=16) 的网络上有t(<=3)小写字母 并且网络上有其大写字母 要求最少的步使得所有小写字母到大写字母里面去 每步可以多个小写字母同时移动(上下左右加不动) 移动后任意两个小写字母不能占用同一个位置 也不能在一步之内进行交换位置
且任何一个2*2子网络中至少有一个障碍格
分析: 小写字母最多三个 已经算是少的了 但是有十六乘十六网络 当有三个小写字母的时候 状态总数为 256的三次方 每次状态转移有 5的三次方枚举量 普通bfs肯定是超时的
题目已经暗示了大部分格子都是障碍 因此应该把所有的状态列出来 形成一张图 而不是临时判断五种方案是否合理
过程:先是给所有有效格标号 储存 然后枚举所有的状态 (我现在还是不懂这有什么区别 一个是在main里面判断地图 一个是在bfs里面判断地图 总的枚举量也没有减少?)
然后状态压缩就十分巧妙了 因为格子最多标号为 十六乘十六等于二百五十六 为0xff 为2的八次方 所以左移八位 要得到改状态时右移 取&0xff
还有就是当字母不满三个的时候 加至三个 方便处理 因为状态压缩的相关都是以三个为基准的
看到bfs先判断枚举量 因为这种bfs和我之前做的普通bfs不同 标记数组状态很多 所以要谨慎
#include<bits/stdc++.h>
using namespace std;
#define N 150
int dis[N];
int n,m,t;
char mp[N][N];
int id[N][N];
int x[N];
int y[N];
int s[];
int e[];
int G[N][N];
int vis[N][N][N];
int dx[]={,,,,-};
int dy[]={,,-,,};
bool judge(int x,int x1,int y,int y1)
{
if(x1==y1||(x==y1&&x1==y) )
return ;
return ;
} int id1(int a,int b,int c)
{
return (a<<)|(b<<)|c;
} bool inmap(int x,int y)
{
if(x>=&&x<=n&&y>=&&y<=m)
return ;
return ;
} int bfs()
{
memset(vis,-,sizeof( vis));
queue<int>q;
q.push( id1(s[],s[],s[]) );
vis[s[]][s[] ][s[] ]=; while(!q.empty())
{
int u=q.front();q.pop();
int a = (u>>)&0xff, b = (u>>)&0xff, c = u&0xff;
printf("%d %d %d\n",a,b,c);
if(a==e[]&&b==e[]&&c==e[])return vis[a][b][c];
for(int i=;i<dis[a];i++)
{
int a2=G[a][i];
for(int j=;j<dis[b];j++)
{
int b2=G[b][j];
if(!judge(a,a2,b,b2))continue;
for(int k=;k<dis[c];k++)
{
int c2=G[c][k];
if(!judge(a,a2,c,c2))continue;
if(!judge(b,b2,c,c2))continue;
if(vis[a2][b2][c2]!=-)continue;
vis[a2][b2][c2]=vis[a][b][c]+;
q.push( id1(a2,b2,c2) );
}
}
}
}
return -;
} int main()
{
while(scanf("%d%d%d",&m,&n,&t)&&t)
{
getchar();
for(int i=;i<n;i++)
fgets(mp[i],,stdin); int cnt=;int goal=;
for(int i=;i<n;i++)
for(int j=;j<m;j++)
if(mp[i][j]!='#')
{
id[i][j]=cnt;
x[cnt]=i;y[cnt]=j;
if(islower(mp[i][j])){s[ mp[i][j]-'a' ]=cnt; }
if(isupper(mp[i][j])){e[ mp[i][j]-'A' ]=cnt; }
cnt++;
} printf("%d %d %d\n",s[],s[],s[]);
printf("%d %d %d\n",e[],e[],e[]); for(int i=;i<cnt;i++)
{
dis[i]=;
for(int k=;k<;k++)
{
int nx=x[i]+dx[k];
int ny=y[i]+dy[k];
if(inmap(nx,ny)&&mp[nx][ny]!='#')G[i][dis[i]++ ]=id[nx][ny];
}
}
if(t<=){dis[cnt]=;G[cnt][]=cnt;s[]=e[]=cnt++;}
if(t<=){dis[cnt]=;G[cnt][]=cnt;s[]=e[]=cnt++;}
printf("%d\n",bfs());
}
return ;
}
7-9The Morning after Halloween uva1601的更多相关文章
- The Morning after Halloween uva1601
这道题思路还是比较清晰的,建图加bfs或双向bfs,其实后者比前者少了将近一半的时间.. 建图可以把某一点所拥有邻接点长度(数目)记录在数组0这个位置,因为这道题使用vector会超时. #inclu ...
- UVA1601 The Morning afther Halloween
题目大意 w h (w, h <= 16)的网格有 n ( n <= 3) 个小写字母(代表鬼)其余的是‘#’(代表障碍格) 或 ‘ ’(代表空格. 要求把他们移动到对应的大写字母里.每步 ...
- 【例题 7-9 UVA-1601】The Morning after Halloween
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 对于没有出现的,当成0节点就好. 所以总是认为有3个人需要走到各自的终点. 将平面图转成点边图.这样比较好枚举. (二维变成一维,模 ...
- UVa1601 - The Morning after Halloween [单向bfs]
解题思路: 1.注意到2*2方格中必有一个#,那么最多只有192条通道,可以将所有非‘#’的位置提取出来用邻接表的方式建图,通过bfs搜索目标位置. 2.将三个ghost的位置(a,b,c)作为状态量 ...
- UVa 1601 || POJ 3523 The Morning after Halloween (BFS || 双向BFS && 降维 && 状压)
题意 :w*h(w,h≤16)网格上有n(n≤3)个小写字母(代表鬼).要求把它们分别移动到对应的大写字母里.每步可以有多个鬼同时移动(均为往上下左右4个方向之一移动),但每步结束之后任何两个鬼不能占 ...
- POJ 3370. Halloween treats 抽屉原理 / 鸽巢原理
Halloween treats Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 7644 Accepted: 2798 ...
- Lightoj 题目1422 - Halloween Costumes(区间DP)
1422 - Halloween Costumes PDF (English) Statistics Forum Time Limit: 2 second(s) Memory Limit: 32 ...
- CSUFT 1004 This is Halloween: Saving Money
1004: This is Halloween: Saving Money Time Limit: 1 Sec Memory Limit: 128 MB Submit: 11 So ...
- [POJ 3370] Halloween treats
Halloween treats Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 7143 Accepted: 2641 ...
随机推荐
- bzoj4807 車
题目大意: Description 众所周知,車是中国象棋中最厉害的一子之一,它能吃到同一行或同一列中的其他棋子.車跟車显然不能在一起打 起来,于是rly一天又借来了许多许多的車在棋盘上摆了起来……他 ...
- (转)Maven学习总结(七)——eclipse中使用Maven创建Web项目
孤傲苍狼只为成功找方法,不为失败找借口! Maven学习总结(七)——eclipse中使用Maven创建Web项目 一.创建Web项目 1.1 选择建立Maven Project 选择File -&g ...
- 5: EL 表达式小结
1.EL表达式的语法格式很简单: 以前编写jsp代码时,如果要获取表单中的用户名,一般使用 <%=request.getParameter("name")%> ,这样 ...
- haoi2006_受欢迎的牛_Solution
Brief Solution: 强连通tarjan+压缩点+判断是否除了一个点,其它点都有出度 Detailed Solution: 把牛看成点若一个点b能到达点a,则b认为a受欢迎若所有的点都能到达 ...
- 将句子表示为向量(下):基于监督学习的句子表示学习(sentence embedding)
1. 引言 上一篇介绍了如何用无监督方法来训练sentence embedding,本文将介绍如何利用监督学习训练句子编码器从而获取sentence embedding,包括利用释义数据库PPDB.自 ...
- 安装【Jenkins】
前言 jenkins的一款持续集成工具, 它可以做的事情很多,其中一个主要的功能就是简化部署流程 回想一下我们的发布流程: 1.本地把项目打包 ...
- win32 ini
原文:https://www.cnblogs.com/qq78292959/archive/2012/06/10/2544389.html Windows操作系统专门为此提供了6个API函数来对配置设 ...
- disabled属性对form表单向后台传值的影响
在form表单里,如果对input加入disabled="disabled"或disabled="true"等属性,form表单提交的时候,就不会传值到后台. ...
- 一个Zabbix agent配置多个Zabbix Server
环境说明: 公司和政府合作的项目中,需要对服务器添加监控.政府方面已对服务部署了zabbix agent,实现了系统层面的基础监控:而对于公司而言,需要对服务器上的服务进行监控,故需在原有的zabbi ...
- 读asyncio模块源码时的知识补漏
硬着头皮看了一周的asyncio模块代码,了解了大概的执行流程,引用太多,成尤其是对象间函数的引用. 光是这么一段简单的代码: # coding: utf8 import asyncio import ...