这题可以用普通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的更多相关文章

  1. The Morning after Halloween uva1601

    这道题思路还是比较清晰的,建图加bfs或双向bfs,其实后者比前者少了将近一半的时间.. 建图可以把某一点所拥有邻接点长度(数目)记录在数组0这个位置,因为这道题使用vector会超时. #inclu ...

  2. UVA1601 The Morning afther Halloween

    题目大意 w h (w, h <= 16)的网格有 n ( n <= 3) 个小写字母(代表鬼)其余的是‘#’(代表障碍格) 或 ‘ ’(代表空格. 要求把他们移动到对应的大写字母里.每步 ...

  3. 【例题 7-9 UVA-1601】The Morning after Halloween

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 对于没有出现的,当成0节点就好. 所以总是认为有3个人需要走到各自的终点. 将平面图转成点边图.这样比较好枚举. (二维变成一维,模 ...

  4. UVa1601 - The Morning after Halloween [单向bfs]

    解题思路: 1.注意到2*2方格中必有一个#,那么最多只有192条通道,可以将所有非‘#’的位置提取出来用邻接表的方式建图,通过bfs搜索目标位置. 2.将三个ghost的位置(a,b,c)作为状态量 ...

  5. UVa 1601 || POJ 3523 The Morning after Halloween (BFS || 双向BFS && 降维 && 状压)

    题意 :w*h(w,h≤16)网格上有n(n≤3)个小写字母(代表鬼).要求把它们分别移动到对应的大写字母里.每步可以有多个鬼同时移动(均为往上下左右4个方向之一移动),但每步结束之后任何两个鬼不能占 ...

  6. POJ 3370. Halloween treats 抽屉原理 / 鸽巢原理

    Halloween treats Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 7644   Accepted: 2798 ...

  7. Lightoj 题目1422 - Halloween Costumes(区间DP)

    1422 - Halloween Costumes   PDF (English) Statistics Forum Time Limit: 2 second(s) Memory Limit: 32 ...

  8. CSUFT 1004 This is Halloween: Saving Money

    1004: This is Halloween: Saving Money Time Limit: 1 Sec      Memory Limit: 128 MB Submit: 11      So ...

  9. [POJ 3370] Halloween treats

    Halloween treats Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 7143   Accepted: 2641 ...

随机推荐

  1. 算法学习——从bzoj2286开始的虚树学习生活

    [原创]转载请标明原作者~ http://www.cnblogs.com/Acheing/ 题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2 ...

  2. winform里宿主WCF,并传递winform变量给WCF

    最近客户要求把服务器端程序里的二个功能用service的方式提供出来,方便调用.首先想着单独建一个wcf 服务的项目,但是因为要用到server端程序winform里的变量,因此只能在winform里 ...

  3. XStream--java对象与xml形式文件相互转换

    1.pom.xml中添加依赖 <dependency> <groupId>com.thoughtworks.xstream</groupId> <artifa ...

  4. mes平台Action类模版

    Connection conn = null; PreparedStatement pst = null; ResultSet rs = null; @Override public String e ...

  5. Activiti学习——Activiti与Spring集成

    转: Activiti学习——Activiti与Spring集成 与Spring集成 基础准备 目录结构 相关jar包 Activiti的相关jar包 Activiti依赖的相关jar包 Spring ...

  6. Spring MVC测试框架

    原文链接:http://jinnianshilongnian.iteye.com/blog/2004660 Spring MVC测试框架详解——服务端测试 博客分类: springmvc杂谈 spri ...

  7. SQL记录-PLSQL字符串

    PL/SQL字符串 PL/SQL字符串实际上是一个可选的尺寸规格字符序列.字符可以是数字,字母,空白,特殊字符或全部的组合. PL/SQL提供了三种类型的字符串: 固定长度字符串:在这样的字符串,程序 ...

  8. 数学:莫比乌斯反演-GCD计数

    Luogu3455:莫比乌斯反演进行GCD计数 莫比乌斯反演就是用来解决这一类问题的,通常f函数是要求的那个,F函数是显然的 这样利用F的结果就可以推出来f的结果 在计算结果的时候整除分快儿一下就可以 ...

  9. web html 基础2

    1.表格<table> 行 tr,没有列的说法,只是单元格td table里面只能仿tr,tr里面只能放td,td可以嵌套任何标签 表格属性 border 边框, cellspacing ...

  10. javascript强大的日期函数

    var date = function( a, s ) { var d = s ? new Date( s ) : new Date(), f = d.getTime(); return ( '' + ...