码迷,mamicode.com
首页 > 其他好文 > 详细

搜索基础题

时间:2014-10-25 17:04:36      阅读:273      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   color   io   os   ar   for   sp   

 

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

题意:在一个仅有红黑格子组成的矩形中,一个人只能走上下左右相邻黑色格子,问从起点开始共能走多少个格子?

’#‘:红色格子

’.‘: 黑色格子;

’@‘:起点 

BFS 和 DFS 都可以遍历所有走的点,每次走过一点时,计数++即可;

 

 

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

由题可知,在限制转弯数量的前提下 能够从一点走到另一个点即可;BFS 和 DFS都能求出解。我 DFS 还没实现

需要注意:1.点坐标是从 1 开始的。

     2.最短的路径可能不满足转弯数的限制。

     3.起点与终点重合。

超内存代码:还没找到原因。

bubuko.com,布布扣
 1 #include <cstdio>
 2 #include <cstring>
 3 #include <queue>
 4 using namespace std;
 5 #define N 105
 6 
 7 struct Pos
 8 {
 9     int x, y;
10     int turn;
11     int dire;
12 }S, E;
13 char map[N][N];
14 bool used[N][N][12][4];
15 int dir[][2]={1,0, -1,0, 0,1, 0,-1};
16 int n, m, k;
17 
18 bool Judge (Pos s)
19 {
20     if (s.x>=1 && s.x<=m && s.y>=1 && s.y<=n && map[s.x][s.y]==. && !used[s.x][s.y][S.turn][S.dire] && s.turn <= k)
21         return true;
22     return false;
23 }
24 
25 bool  bfs ()
26 {
27     Pos Pre, Cur;
28     queue <Pos> Q;
29     while (!Q.empty ()) Q.pop();
30     memset (used, 0, sizeof used);
31 
32     S.dire = -1;
33     S.turn = 0;
34     used[S.x][S.y][S.turn][S.dire] = true;
35     Q.push (S);
36     while (!Q.empty ())
37     {
38         Pre = Q.front ();
39         Cur = Pre;
40         Q.pop();
41         if (Cur.x==E.x && Cur.y==E.y)
42             return true;
43         for(int i=0; i<4; i++)
44         {
45             Cur.x = Pre.x + dir[i][0];
46             Cur.y = Pre.y + dir[i][1];
47             Cur.turn = Pre.turn;
48             Cur.dire = i;
49             if (Cur.dire != Pre.dire && Pre.dire !=-1)
50                 Cur.turn++;
51             if (Judge (Cur))
52             {
53                 used[Cur.x][Cur.y][Cur.turn][Cur.dire] = true;
54                 Q.push (Cur);
55             }
56         }
57     }
58     return false;
59 }
60 
61 int main ()
62 {
63     int t;
64 //    freopen ("test.txt","r",stdin);
65     scanf ("%d",&t);
66     while (t--)
67     {
68         scanf ("%d%d",&m, &n);
69         for (int i=1; i<=m; i++)
70             for (int j=1; j<=n; j++)
71                 scanf (" %c", map[i]+j);
72         scanf ("%d%d%d%d%d",&k, &S.y, &S.x, &E.y, &E.x);
73 
74         puts ((bfs ()?"yes":"no"));
75     }
76     return 0;
77 }
View Code

 

1.http://acm.hdu.edu.cn/showproblem.php?pid=1010;

题意:在一个矩形的迷宫里面, 问是否可以恰好在 给定的时间点 走到出口。

‘X‘:墙壁;

’S‘:起点;

‘D‘:出口;

’.‘: 空地。

这道题,是问你是否有解,不是要求最优解,所以可以用DFS深度搜索,  奇偶性剪枝+路径剪枝优化时间防TLE。如果硬是要用BFS按理来说应该是可以求出结果的,不过我BFS一直WA,一直想不通。留着以后进步了再斟酌。

DFS代码:

bubuko.com,布布扣
 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cmath>
 4 using namespace std;
 5 
 6 int n, m, t, ex, ey;
 7 char map[10][10];
 8 bool visit[10][10], flag;
 9 int dir[][2]={1,0, -1,0, 0,1, 0,-1};
10 
11 void dfs (int x, int y, int cnt)
12 {
13     if (x<0 || x>n-1 || y<0 || y>m-1) return;
14     if (flag || cnt > t) return;
15     if (x==ex && y==ey)
16     {
17         if (cnt == t)
18             flag = true;
19         return;
20     }
21     for (int i=0; i<4; i++)
22     {
23         int xx = x + dir[i][0];
24         int yy = y + dir[i][1];
25         if (map[xx][yy]==X || visit[xx][yy]) continue;
26         visit[xx][yy] = true;
27         dfs (xx, yy, cnt+1);
28         if (flag) return;
29         visit[xx][yy] = false;
30     }
31 }
32 int main ()
33 {
34 //    freopen ("test.txt","r",stdin);
35     while (~scanf ("%d%d%d",&n, &m, &t) && n+m+t)
36     {
37         int wall=0, sx, sy;
38         for (int i=0; i<n; i++)
39             for (int j=0; j<m; j++)
40             {
41                 scanf (" %c",map[i]+j);
42                 if (map[i][j] == S)
43                 {
44                     sx = i; sy = j;
45                 }
46                 else if (map[i][j]==D)
47                 {
48                     ex = i; ey = j;
49                 }
50                 else if (map[i][j]==X)
51                     wall++;
52             }
53         //路径剪枝
54         if (n*m-wall < t)
55         {
56             puts ("NO");
57             continue;
58         }
59         //奇偶性剪枝
60         int tmp = fabs (sx-ex) + fabs (sy-ey);
61         if ((t - tmp) & 1)
62         {
63             puts ("NO");
64             continue;
65         }
66         memset (visit, 0, sizeof visit);
67         flag = false;
68         visit[sx][sy] = true;
69         dfs(sx, sy, 0);
70         puts ((flag?"YES":"NO"));
71     }
72     return 0;
73 }
View Code

 

搜索基础题

标签:style   blog   http   color   io   os   ar   for   sp   

原文地址:http://www.cnblogs.com/khan724/p/4050344.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!