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 ...
随机推荐
- (转)java中使用memcache
背景:公司项目中使用java和memcache相结合来搭建缓存,所以要了解下缓存的基础知识! 1 了解memcache 1.1 基础知识 什么是Memcache? Memcache集群环境下缓存解决方 ...
- Tensorflow图像处理
Tensorflow图像处理主要包括:调整尺寸,图像翻转,调整色彩,处理标注框. 代码如下: #coding=utf-8 import matplotlib.pyplot as plt import ...
- 形参与实参的区别---java基础
1.形参变量只有在被调用时才分配内存单元,在调用结束时,即刻释放所分配的内存单元.因此,形参只在函数内部有效.函数调用结束返回主调用函数后则不能再使用该形参变量.2.实参可以是常量.变量.表达式.函数 ...
- POJ - 2299 Ultra-QuickSort(归并排序)
https://vjudge.net/problem/POJ-2299 题意 求对于给定的无序数组,求出经过最少多少次相邻元素的交换之后,可以使数组从小到大有序. 分析 很明显是求逆序对的数目,那就要 ...
- Dubbo学习笔记4:服务消费端泛化调用与异步调用
本文借用dubbo.learn的Dubbo API方式来解释原理. 服务消费端泛化调用 前面我们讲解到,基于Spring和基于Dubbo API方式搭建简单的分布式系统时,服务消费端引入了一个SDK二 ...
- BSGS 算法
求解 A^x ≡ B mod C C是质数 的最小非负整数解 证明:A^x ≡ A^(x%φ(C)) mod C A^(x%φ(C)) ≡ A^(x-k*φ(C)) ≡ (A^x)/ A^(k*φ ...
- OpenGL ES 2.0 Shader 调试新思路(二): 做一个可用的原型
OpenGL ES 2.0 Shader 调试新思路(二): 做一个可用的原型 目录 背景介绍 请参考前文OpenGL ES 2.0 Shader 调试新思路(一): 改变提问方式 优化 ledCha ...
- 测试浏览器是否支持某个CSS属性
花了几个小时写了个API,为了兼容多种用法和测试花了不少时间,求鞭打.嘲笑和建议. <!DOCTYPE HTML> <html lang="zh-CN"> ...
- 阿里云Linux服务器安装 nginx+mysql+php
阿里云Linux服务器安装 nginx+mysql+php步骤1.登录服务器2.下载安装包3.将安装包上传到服务器的/home目录下 注:使用rz sz命令进行本地和服务器间的上传.下载,安装命令yu ...
- 20155212 2016-2017-2 《Java程序设计》第6周学习总结
20155212 2016-2017-2 <Java程序设计>第6周学习总结 教材学习内容总结 Chapter10 输入串流为java.io.InputStream,输出串流为java.i ...