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 ...
随机推荐
- CODE FESTIVAL 2017 qual A 题解
补一发A的题解. A - Snuke's favorite YAKINIKU 题意: 输入字符串S,如果以YAKI开头输出Yes,否则输出No. #include<bits/stdc++.h&g ...
- 使用ImageMagick 在图片上绘制粗斜体的中文也许是一个错误。
测试发现: ImageMagick使用中文字体,在图片上绘制带粗或斜体的中文,看不到效果. 如果使用英文字体,绘制粗或斜体的英文,99%都有效果. 今天无意看到一篇文章提到: convert -lis ...
- mysqldump --master-data=2 --single-transaction
转载于https://blog.csdn.net/linuxheik/article/details/714808821 mysqldump导出数据主要有两种控制:一种是导出的全过程都加锁 lock- ...
- Vue单页面应用阻止浏览器记住密码
Vue单页面应用阻止浏览器记住密码 ——IT唐伯虎 摘要: Vue单页面应用阻止浏览器记住密码. 现象1:路由切换时再次提示“是否记住密码” 登录页面有个密码输入框,输入账号密码进行登录: 登录完成后 ...
- spectrogram函数做短时傅里叶分析
整理自:http://blog.sina.com.cn/s/blog_6163bdeb0102dwfw.html 今天偶人发现原来matlab自带了短时傅里叶变换的分析函数,老版本的matlab是sp ...
- OpenStack中RabbitMQ高可用性配置
采用镜像队列的方案进行配置 1. 网络拓扑 node1:10.10.11.1 node2:10.10.11.2 2. 配置hosts node1+node2: vim /etc/hosts >1 ...
- centos6.x下安装maven
转自:http://www.centoscn.com/image-text/install/2014/0507/2923.html 1.下载maven包首先从官网上 http://maven.apac ...
- Confluence wiki——CentOS6.8搭建详解
参考资料:http://www.cnblogs.com/jackyyou/p/5534231.html http://www.ilanni.com/?p=11989 公司需要搭建WIKI方便员工将一些 ...
- Java入门系列(九)Java API
String,StringBuilder,StringBuffer三者的区别 1.首先说运行速度,或者说是执行速度 在这方面运行速度快慢为:StringBuilder > StringBuffe ...
- 如何使用ASP.NET开发基于推技术的聊天室?
public class Content : System.Web.UI.Page{private void Page_Load(object sender, System.EventArgs e){ ...