poj 4105 拯救公主(bfs)

原题网址:http://bailian.openjudge.cn/practice/4105/

思路:

每个位置包括的状态:所在的位置,获得的宝石。

广搜:用队列存储达到某个位置时,获得的宝石完全相同的最少用时。

传送门另外考虑即可。

详细代码:

 1 #include <cstdio>
 2 #include <queue>
 3 #include <cstring>
 4 using namespace std;
 5
 6 const int INF = 0x44444444;
 7 int gater[10], gatec[10], cnt, n,m, k, dp[210][210][1<<5],// 存储传送门的数量,到大某个位置时,获得宝石完全相同时的最少用时
 8     ex,ey;
 9 char mp[210][210];
10 queue<int> que;
11
12 int main(){
13     freopen("C:\\Users\\yyf\\Documents\\CppFiles\\in.txt", "r", stdin);
14     int t,dx[4]={1,0,-1,0},dy[4]={0,1,0,-1};
15     scanf("%d", &t);
16     while(t--){
17         cnt=0;
18         memset(dp, 0x44, sizeof(dp));
19         scanf("%d%d%d", &n, &m, &k);
20         for(int i=0; i<n; ++i){
21             scanf("%s", mp[i]);
22             for(int j=0; j<m; ++j){
23                 switch(mp[i][j]){
24                     case ‘$‘:     gater[cnt]=i;gatec[cnt++]=j;
25                                 break;
26                     case ‘S‘:     que.push(i), que.push(j), que.push(0);
27                                   dp[i][j][0]=0;
28                                   break;
29                     case ‘E‘:     ex=i, ey=j; break;
30                     default :     break;
31                 }
32             }
33         }
34         while(!que.empty()){
35             int tr = que.front(); que.pop();
36             int tc = que.front(); que.pop();
37             int ts = que.front(); que.pop();
38             for(int i=0; i<4; ++i){// 四个方向
39                 int r=tr+dx[i], c=tc+dy[i];
40                 if(r<0 || c<0 || r==n || c==m || mp[r][c]==‘#‘) continue;
41                 int t = dp[tr][tc][ts]+1, s=ts;
42                 if(‘0‘<=mp[r][c] && mp[r][c]<=‘4‘){
43                     s |= 1<<mp[r][c]-‘0‘;
44                 }
45                 if(t>=dp[r][c][s]) continue;// 剪枝
46                 if(mp[r][c]==‘$‘){
47                     for(int j=0; j<cnt; ++j){
48                         dp[gater[j]][gatec[j]][s] = t;
49                         que.push(gater[j]), que.push(gatec[j]);
50                         que.push(s);
51                     }
52                 }
53                 else {
54                     dp[r][c][s]=t;
55                     if(mp[r][c]==‘E‘ && s==(1<<k)-1) continue;
56                     que.push(r), que.push(c), que.push(s);
57                 }
58             }
59         }
60         if(dp[ex][ey][(1<<k)-1] == INF) printf("oop!\n");
61         else printf("%d\n", dp[ex][ey][(1<<k)-1]);
62     }
63     return 0;
64 }
时间: 2024-08-04 01:57:24

poj 4105 拯救公主(bfs)的相关文章

poj 1724 ROADS (bfs+优先队列)

题目链接 题意:在有费用k限制的条件下,求从1到n的最短距离,如果最短距离相同求费用最小的,边为有向边,其中可能有 多个相同的源点和目标点,但是距离和费用不同. 分析:用bfs和邻接表来把每一个边搜一下,因为用了优先队列,所以先到n的一定是最小的 . 1 #include <iostream> 2 #include <cstring> 3 #include <cstdlib> 4 #include <cmath> 5 #include <cstdio&

POJ 3287 (基础BFS) Catch That Cow

这是做的第一道BFS,很基础很简单的题目 广度优先搜索算法如下:(用QUEUE)(1) 把初始节点S0放入Open表中:(2) 如果Open表为空,则问题无解,失败退出:(3) 把Open表的第一个节点取出放入Closed表,并记该节点为n:(4) 考察节点n是否为目标节点.若是,则得到问题的解,成功退出:(5) 若节点n不可扩展,则转第(2)步:(6) 扩展节点n,将其不在Closed表和Open表中的子节点(判重)放入Open表的尾部,并为每一个子节点设置指向父节点的指针(或记录节点的层次)

poj 1724ROADS(bfs和dfs做法)

1 /* 2 dfs比较好想,就是测试数据的问题,导致在遍历边的时候要倒着遍历才过! 3 */ 4 #include<iostream> 5 #include<cstdio> 6 #include<cstring> 7 #include<vector> 8 #include<algorithm> 9 #define Max 0x3f3f3f3f 10 using namespace std; 11 12 struct node{ 13 int D

poj 1915 双向 BFS 利用数组 a[x][y] = a[cp.x][cp.y] + 1; b[x][y] = b[cp.x][cp.y] + 1;保留步数

#include<iostream>#include<queue> using namespace std; struct point{    int x, y;};point bufa[8] ={    {-2, 1}, {-1, 2}, {1, 2}, {2, 1},    {2, -1}, {1, -2}, {-1, -2}, {-2, -1}}; int n, a[305][305], b[305][305]; int rule(int x,int y)//判断是否符合棋盘

poj 1562 简单 bfs

// 简单 bfs #include <iostream>#include<fstream>using namespace std; char map[110][110];int flag[110][110];int qu[11000][2],qe,qs,m,n;int add[8][2]={-1,-1,  -1,0, -1,1,   0,-1,  0,1,  1,-1,    1,0,   1,1 }; void bfs(int r,int c){    int i,tr,tc;

POJ 3026(BFS+prim)

http://poj.org/problem?id=3026 题意:任意两个字母可以连线,求把所有字母串联起来和最小. 很明显这就是一个最小生成树,不过这个题有毒.他的输入有问题.在输入m和N后面,可能有一大串的空格.就因为这个,我RE都有点懵了,要不是discuss里面有人说输入有问题,我都没注意到这个,原本只用了一个getchar吃掉最后的换行符.没想到之后还有空格.有点小坑. 思路:这个题目如果他给你一个图,那就是最裸的prim了.不过这个题的难点也就是在他给的图你不能用Prim,你只能通

POJ 3414 Pots (BFS + 记录路径)

Pots Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 10300 Accepted: 4362 Special Judge Description You are given two pots, having the volume of A and B liters respectively. The following operations can be performed: FILL(i)        fill th

POJ 1736 Robot BFS

Robot Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 7561   Accepted: 2444 Description The Robot Moving Institute is using a robot in their local store to transport different items. Of course the robot should spend only the minimum time

POJ 3126 primepath bfs

题目链接:http://poj.org/problem?id=3126 题意:1维的坐标轴,给出起点和终点,求从起点到终点变换经历的最短的步数.起点,终点和中间变换的数字都是4位,而且都是质数. 思路:普通的广搜.精神状态不佳.找了许久的bug.后来发现是prime函数和pow函数都很丧心病狂的写错了. 附 AC 代码: 1 // T_T 电脑突然重启什么都没有了..没有了. 2 //大概4*9入口的广搜. 从初始点开始 对于每个扩展点加入队列 知道找到ed.或者尝试完所有可能的情况. 3 4