hdu - 2216 Game III && xtu 1187 Double Maze (两个点的普通bfs)

http://acm.hdu.edu.cn/showproblem.php?pid=2216

zjt和sara在同一个地图里,zjt要去寻找sara,zjt每移动一步sara就要往相反方向移动,如果他们相邻或者在同一个格子里就算相遇。

输出最少步数。注意zjt每次必须要有能移动的点才移动,否则不能移动,但是sara没有能移动的点的话可以呆着不动。

用结构体保存两个点和相应的步数作为一个状态,然后用哈希函数映射出每一个状态的的哈希值,放入set中,判重。

注意哈希函数的选取要确保不能重复。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #include <queue>
 6 #include <set>
 7
 8 using namespace std;
 9
10 struct PT
11 {
12     int x1,y1,x2,y2;
13     int step;
14 };
15
16 const int dir_x[4]={1,0,0,-1};
17 const int dir_y[4]={0,-1,1,0};
18 char mp[25][25];
19 int n,m;
20
21 int ha(int a,int b,int c,int d)
22 {
23     int ret=a;
24     ret=ret*100+b;
25     ret=ret*100+c;
26     ret=ret*100+d;
27     return ret;
28 }
29
30 int main()
31 {
32     //freopen("a.txt","r",stdin);
33     while(scanf("%d%d",&n,&m)!=EOF)
34     {
35         int a=0,b=0,c=0,d=0;
36         for(int i=0;i<n;i++) scanf("%s",mp[i]);
37         for(int i=0;i<n;i++)
38         {
39             for(int j=0;j<m;j++)
40             {
41                 if(mp[i][j]==‘Z‘)
42                 {
43                     a=i;b=j;
44                 }
45                 else if(mp[i][j]==‘S‘)
46                 {
47                     c=i;d=j;
48                 }
49             }
50         }
51         //printf("%d %d %d %d\n",a,b,c,d);
52         PT ac=(PT){a,b,c,d,0};
53
54         queue<PT> q;
55         q.push(ac);
56         set<int> st;
57         st.insert(ha(a,b,c,d));
58         bool flag=false;
59         while(!q.empty())
60         {
61             PT u=q.front(),v; q.pop();
62             int x=abs(u.x1-u.x2)+abs(u.y1-u.y2);
63             if(x==0||x==1) //相邻或者相遇
64             {
65                 printf("%d\n",u.step);
66                 flag=true;
67                 break;
68             }
69             for(int i=0;i<4;i++)
70             {
71                 int X1=u.x1+dir_x[i],X2=u.x2-dir_x[i];
72                 int Y1=u.y1+dir_y[i],Y2=u.y2-dir_y[i];
73                 if(X1<0||X1>=n||Y1<0||Y1>=m||mp[X1][Y1]==‘X‘)
74                 {
75                     continue;
76                 }
77                 if(X2<0||X2>=n||Y2<0||Y2>=m||mp[X2][Y2]==‘X‘)
78                 {
79                     X2=X2+dir_x[i];Y2=Y2+dir_y[i];
80                 }
81               //  printf("%d %d %d %d\n",X1,Y1,X2,Y2);
82                 int xx=u.step+1;
83                 int h=ha(X1,Y1,X2,Y2);
84                 if(!st.count(h))
85                 {
86                     st.insert(h);
87                     v=(PT){X1,Y1,X2,Y2,xx};
88                     q.push(v);
89                 }
90             }
91         }
92         if(!flag) cout<<"Bad Luck!\n";
93     }
94     return 0;
95 }
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <set>

using namespace std;

struct point
{
    int x1,y1,x2,y2;
    int step;
};

const int dx[4]={1,0,0,-1};
const int dy[4]={0,-1,1,0};
char mp[25][25];
int n,m;
int used[25][25][25][25];
bool flag;

void bfs(point s)
{
    memset(used,0,sizeof(used));
    queue<point>que;
    que.push(s);
    used[s.x1][s.y1][s.x2][s.y2]=1;
    while(!que.empty())
    {
        point e=que.front(); que.pop();
        int x=abs(e.x1-e.x2)+abs(e.y1-e.y2);
       // printf("%d %d %d %d\n",e.x1,e.y1,e.x2,e.y2);
        if(x==0||x==1)
        {
            flag=1;
            printf("%d\n",e.step);
            return;
        }
        for(int i=0;i<4;i++)
        {
            s=e;
            s.x1=e.x1+dx[i];s.y1=e.y1+dy[i];
            if(s.x1<0||s.x1>=n||s.y1<0||s.y1>=m||mp[s.x1][s.y1]==‘X‘) continue;
            s.x2=e.x2-dx[i];s.y2=e.y2-dy[i];
            if(s.x2<0||s.x2>=n||s.y2<0||s.y2>=m||mp[s.x2][s.y2]==‘X‘)
            {
                s.x2+=dx[i];s.y2+=dy[i];
            }
            if(!used[s.x1][s.y1][s.x2][s.y2])
            {
                used[s.x1][s.y1][s.x2][s.y2]=1;
                s.step+=1;
                que.push(s);
            }
        }
    }
}
int main()
{
    //freopen("a.txt","r",stdin);
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        point s;
        for(int i=0;i<n;i++) scanf("%s",mp[i]);
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            {
                if(mp[i][j]==‘Z‘)
                {
                    s.x1=i;s.y1=j;
                }
                else if(mp[i][j]==‘S‘)
                {
                    s.x2=i;s.y2=j;
                }
            }
        }
        s.step=0;
        flag=0;
        bfs(s);
        if(!flag) printf("Bad Luck!\n");
    }
    return 0;
}

http://202.197.224.59/OnlineJudge2/index.php/Problem/read/id/1187

这道题以前看到没有思路去做,今天终于ac了。

跟上面一道题不同的是这里两个点是按照相同的指令移动,并且如果发出指令之后移动到了不合法的位置那么就忽略这条指令那么点应该返回到原来的位置,但是在还是需要记录这条指令  还有一个坑点是输出尽可能短的指令,如果长度相同输出字典序最小的指令,所以遍历四个方向是有先后顺序的,昨晚debug了一个小时才发现这个。

思路跟上面一样。

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <queue>
  4 #include <set>
  5 #include <iostream>
  6 using namespace std;
  7
  8 struct point
  9 {
 10     int x1,y1,x2,y2;
 11     string str;
 12 };
 13
 14 char maze[20][20];
 15 int n,m;
 16 bool flag;
 17 string go;
 18 int dx[4]={1,0,0,-1};
 19 int dy[4]={0,-1,1,0};
 20 char dir[4]={‘D‘,‘L‘,‘R‘,‘U‘}; //注意 顺序必须是这样 跟上面对应
 21 int hash1(point s)
 22 {
 23     int cnt=s.x1;
 24     cnt=cnt*100+s.y1;
 25     cnt=cnt*100+s.x2;
 26     cnt=cnt*100+s.y2;
 27     return cnt;
 28 }
 29
 30 void bfs(point s)
 31 {
 32     queue<point>que;
 33     set<int>st;
 34     que.push(s);
 35     st.insert(hash1(s));
 36     while(!que.empty())
 37     {
 38         point e=que.front(); que.pop();
 39         //printf("%d %d %d %d\n",e.x1,e.y1,e.x2,e.y2);
 40         if(flag&&e.str.size()>go.size()) break;
 41         if(e.x1==e.x2&&e.y1==e.y2)
 42         {
 43            // cout<<e.str<<endl;
 44             if(go.size()==0)
 45             {
 46                 go=e.str;
 47             }
 48             else if(go>e.str) go=e.str;
 49             flag=true;
 50         }
 51         for(int i=0;i<4;++i)
 52         {
 53             s.x1=e.x1+dx[i],s.x2=e.x2+dx[i];
 54             s.y1=e.y1+dy[i],s.y2=e.y2+dy[i];
 55            // printf("%d %d %d %d     \n",s.x1,s.y1,s.x2,s.y2);
 56             if(s.x1<0||s.x1>=n||s.y1<0||s.y1>=m||maze[s.x1][s.y1]==‘#‘)
 57             {
 58                 s.x1-=dx[i];s.y1-=dy[i];
 59             }
 60             if(s.x2<0||s.x2>=n||s.y2<0||s.y2>=m||maze[s.x2][s.y2]==‘#‘)
 61             {
 62                 s.x2-=dx[i];s.y2-=dy[i];
 63             }
 64            // printf("%d %d %d %d\n",s.x1,s.y1,s.x2,s.y2);
 65             s.str=e.str+dir[i];
 66             int h=hash1(s);
 67             if(!st.count(h))
 68             {
 69                 st.insert(h);
 70                 que.push(s);
 71             }
 72         }
 73     }
 74 }
 75
 76 int main()
 77 {
 78    // freopen("data.txt","r",stdin);
 79    // freopen("b.txt","w",stdout);
 80     while(~scanf("%d%d",&n,&m))
 81     {
 82         point s;
 83         s.x1=0,s.y1=0,s.x2=0,s.y2=0,s.str="";
 84         for(int i=0;i<n;i++)
 85         {
 86             scanf("%s",maze[i]);
 87             for(int j=0;j<m;j++)
 88             {
 89                 if(maze[i][j]==‘*‘)
 90                 {
 91                     if(s.x1==0&&s.y1==0)
 92                     {
 93                         s.x1=i;s.y1=j;
 94                     }
 95                     else
 96                     {
 97                         s.x2=i;s.y2=j;
 98                     }
 99                 }
100             }
101         }
102       // printf("%d %d %d %d\n",s.x1,s.y1,s.x2,s.y2);
103         flag=0;
104         go="";
105         bfs(s);
106         if(!flag) cout<<"Sorry"<<endl;
107         else cout<<go<<endl;
108     }
109     return 0;
110 }
时间: 2024-10-13 12:18:33

hdu - 2216 Game III && xtu 1187 Double Maze (两个点的普通bfs)的相关文章

HDU 2216 Game III(BFS)

Problem Description Zjt and Sara will take part in a game, named Game III. Zjt and Sara will be in a maze, and Zjt must find Sara. There are some strang rules in this maze. If Zjt move a step, Sara will move a step in opposite direction.Now give you

hdu 2216 Game III

网上查了标记路径的方法之后就是一道普通的搜索题了,自己还是想不到关键的,努力! #include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> #include <vector> #include <queue> #include <stack> #include <set> #include <map>

hdu3713 Double Maze

Problem Description Unlike single maze, double maze requires a common sequence of commands to solve both mazes. See the figure below for a quick understanding. A maze is made up of 6*6 cells. A cell can be either a hole or a square. Moreover, a cell

HDU 4048 Zhuge Liang&#39;s Stone Sentinel Maze

Zhuge Liang's Stone Sentinel Maze Time Limit: 10000/4000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 385    Accepted Submission(s): 106 Problem Description Zhuge Liang was a chancellor of the state of Shu Han dur

java使double保留两位小数的多方法

java使double保留两位小数的多方法 java保留两位小数 mport java.text.DecimalFormat; DecimalFormat df = new DecimalFormat("######0.00"); double d1 = 3.23456 double d2 = 0.0; double d3 = 2.0; df.format(d1); df.format(d2); df.format(d3); 3个结果分别为: 3.23 0.00 2.00 java保留

ZOJ 3420 Double Maze (BFS)

链接 :  http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3420 普通的BFS 两个图的状态表示成一个状态.记录答案直接用string保存操作. #include <iostream> #include <sstream> #include <cstring> #include <cstdio> #include <vector> #include <stac

hdu 2122(Ice_cream’s world III)(最小生成树,两种算法都可以)

Ice_cream's world III Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 926    Accepted Submission(s): 303 Problem Description ice_cream's world becomes stronger and stronger; every road is built

HDU 3277Marriage Match III(二分+并查集+拆点+网络流之最大流)

题目地址:HDU 3277 这题跟这题的上一版建图方法差点儿相同,仅仅只是须要拆点.这个点拆的也非常巧妙,既限制了流量,还仅仅限制了一部分,曾经一直以为拆点会所有限制,原来也能够用来分开限制,学习了. 建图方法为:建一源点与汇点,将女孩进行拆点,拆成i和i+n,将i与源点连边,权值为mid,将i与i+n连边,权值为k,再将男孩与汇点连边,权值为mid,这时能够配对的就将i与相应的男孩连边,权值为1,不能配对的就将i+n与相应的男孩连边,这种话对原来可配对的不会限制流量,对不能够配对的限制了流量k

hdu 2216 bfs

题目大意:两个东西朝相同方向移动Sample Input4 4XXXX.Z...XS.XXXX4 4XXXX.Z...X.SXXXX4 4XXXX.ZX..XS.XXXXSample Output11Bad Luck! 由于两个棋子必然有一个移动.所以假设其中一个一直移动即可,比较水了 1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #in