zoukankan      html  css  js  c++  java
  • HDU 1010 Tempter of the Bone(DFS+剪枝)

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

    大神题解报告http://acm.hdu.edu.cn/forum/read.php?tid=6158

    1. 关于剪枝,没有剪枝的搜索不太可能,这题老刘上课的时候讲过两个剪枝,一个是奇偶剪枝,一个是路径剪枝

    2. 奇偶剪枝:
    3. 把矩阵标记成如下形式:
    4. 0,1,0,1,0
    5. 1,0,1,0,1
    6. 0,1,0,1,0
    7. 1,0,1,0,1
    8. 很明显,如果起点在0 而终点在1 那显然 要经过奇数步才能从起点走到终点,依次类推,奇偶相同的偶数步,奇偶不同的奇数步
    9. 在读入数据的时候就可以判断,并且做剪枝,当然做的时候并不要求把整个矩阵0,1刷一遍,读入的时候起点记为(Si,Sj) 终点记为(Di,Dj) 判断(Si+Sj) 和 (Di+Dj) 的奇偶性就可以了

    10. 路径剪枝:
    11. 矩阵的大小是N*M 墙的数量记为wall 如果能走的路的数量 N*M - wall 小于时间T,就是说走完也不能到总的时间的,这显然是错误的,可以直接跳出了
      #include <cstdlib>
      #include <cstdio>
      #include <cstring>
      #include <queue>
      #include <cmath>
      using namespace std;
      char map[30][30];
      int vis[30][30];
      int dx[] = {0, 1, 0, -1};
      int dy[] = {1, 0, -1, 0};
      int n, m, t, a, b, flag;
      
      struct point
      {
      	int x, y, step;
      } st;
      
      void dfs(point st);
      
      int main()
      {
      	//freopen("1.txt", "w", stdout);
      
      	while (~scanf("%d%d%d", &m, &n, &t) && (n + m + t != 0))
      	{
      		int wall = 0;
      		flag = 0;
      		memset(map, 0, sizeof(map));
      
      		for (int i = 1; i <= m; i++)
      		{
      			for (int j = 1; j <= n; j++)
      			{
      				scanf(" %c", &map[i][j]);
      
      				if (map[i][j] == 'S')
      				{
      					memset(vis, 0, sizeof(vis));
      					st.x = i;
      					st.y = j;
      					st.step = 0;
      				}
      
      				if (map[i][j] == 'D')
      				{
      					a = i;
      					b = j;
      				}
      
      				if (map[i][j] == 'X')
      				{
      					wall++;
      				}
      			}
      		}
      
      		dfs(st);
      
      		if (flag)
      		{
      			printf("YES
      ");
      		}
      		else
      		{
      			printf("NO
      ");
      		}
      	}
      
      	return 0;
      }
      
      void dfs(point st)
      {
      	int xx = abs(a - st.x), yy = abs(b - st.y), tt = t - st.step;;
      
      	//printf("x=%d,y=%d,t=%d,%d
      ", st.x, st.y, tt, (tt - xx - yy));
      	if(flag == 1)
      	{
      		return; //不加这个会TLE
      	}
      
      	if (tt < 0 || ((tt - xx - yy) % 2 != 0))
      	{
      		return;
      	}
      	else
      	{
      		if (tt == 0)
      		{
      			if (map[st.x][st.y] == 'D')
      			{
      				flag = 1;
      				return;
      			}
      			else
      			{
      				return;
      			}
      
      		}
      		else
      			for (int i = 0; i < 4; i++)
      			{
      				point next = st;
      				next.x = st.x + dx[i], next.y = st.y + dy[i];
      				int nx = next.x, ny = next.y;
      
      				if ((map[nx][ny] == '.' || map[nx][ny] == 'D') && nx > 0 && nx <= m && ny > 0 && ny <= n
      				        &&	!vis[nx][ny])
      				{
      					next.step++;
      					vis[nx][ny] = 1;
      					dfs(next);
      					vis[nx][ny] = 0;
      				}
      			}
      
      	}
      }
      


    www.cnblogs.com/tenlee
  • 相关阅读:
    Object的公用方法
    Java的特点
    Set集合
    Java语言的三大特性
    List集合
    Collection类
    HashSet
    Codeforces1141F2 Same Sum Blocks (Hard)
    Codeforce1176F Destroy it!
    jzoj 5348. 【NOIP2017提高A组模拟9.5】心灵治愈
  • 原文地址:https://www.cnblogs.com/tenlee/p/4420148.html
Copyright © 2011-2022 走看看