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\n");
    		}
    		else
    		{
    			printf("NO\n");
    		}
    	}
    
    	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\n", 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;
    				}
    			}
    
    	}
    }
    


你可能感兴趣的:(HDU 1010 Tempter of the Bone(DFS+剪枝))