zoukankan      html  css  js  c++  java
  • HDU 1254 推箱子游戏(搞了一下午。。。)

    中文题目:http://acm.hdu.edu.cn/showproblem.php?pid=1254
    一开始常规的人用来做主导,想着想着不对劲,其实是箱子为主导,人只是箱子能否推进的一个判断。
    可以使用两个BFS,人这里也可以DFS。看见别人有用四维标记的有用图中图的判重,我也用一下图中图好了。
    
    #include<iostream>     
    #include<queue>
    using namespace std;
    
    int n, m;
    int map[10][10];
    int vec[4][2] = {{-1,0}, {0,1}, {1,0}, {0,-1}};
    int visited[10][10][4];//标记箱子。有四个方向,所有一个点可以推四次
    int visitedP[10][10];//标记人
    
    struct node
    {
    	int x;
    	int y;
    	int step;
    	int innerMap[10][10];//保存每个点修改的图
    	bool check()
    	{
    		if(x>=0 && x<n && y>=0 && y<m)
    			return true;
    		return false;
    	}
    }boxStart, peopleStart, peopleEnd, target;
    
    int PeopleBFS(node t)
    {
        peopleStart = t;
    	memset(visitedP, 0, sizeof(visitedP));
    
    	queue<node> Q;
    	//找人的位置
    	for (int i = 0; i<n; i++)
    	{
    		for (int j = 0; j<m; j++)
    		{
    			if (t.innerMap[i][j] == 4)
    			{
    				peopleStart.x = i;
    				peopleStart.y = j;
    				peopleStart.step = 0;
    			}
    		}
    	}
    	if(peopleStart.x == peopleEnd.x && peopleStart.y == peopleEnd.y)
    		return true;
    	visitedP[peopleStart.x][peopleStart.y] = true;
    
    	Q.push(peopleStart);
    	while (!Q.empty())
    	{
    		node q = Q.front();
    		Q.pop();
    		for (int i = 0; i<4; i++)
    		{
    			node p = q;
    			p.x += vec[i][0];
    			p.y += vec[i][1];
    			p.step++;
    			if (p.check() && !visitedP[p.x][p.y] && t.innerMap[p.x][p.y]!=1
                            && t.innerMap[p.x][p.y]!= 2)//不是墙不是箱
    			{
    				visitedP[p.x][p.y] = true;
    				if (p.x == peopleEnd.x && p.y == peopleEnd.y)//可以到
    				{
    					return true;
    				}
    				Q.push(p);
    			}
    		}
    	}
    	return false;
    }
    
    
    int BoxBFS()
    {
    	queue<node> Q;
    	Q.push(boxStart);
    	while (!Q.empty())
    	{
    	    node q = Q.front();
    		Q.pop();
    		for (int i = 0; i<4; i++)
    		{
    			node p = q;
    			p.x += vec[i][0];
    			p.y += vec[i][1];
    			p.step++;
    			if (p.check() && !visited[p.x][p.y][i] && map[p.x][p.y] != 1)
    			{
    				//找出人站在箱子前进方向的反方向
    				peopleEnd = q;
    				peopleEnd.x = q.x - vec[i][0];
    				peopleEnd.y = q.y - vec[i][1];
    				if (peopleEnd.check())//人可以站在这个位置
    				{
    					if (PeopleBFS(peopleEnd))//人可以到达					{
    						swap(p.innerMap[p.x][p.y], p.innerMap[q.x][q.y]);//箱子走一步
    						swap(p.innerMap[peopleEnd.x][peopleEnd.y],
                         p.innerMap[peopleStart.x][peopleStart.y]);//人跟上					
                                visited[p.x][p.y][i] = true;
    						if (map[p.x][p.y] == 3)//到达目的地
    						{
    							return p.step;
    						}
    					    Q.push(p);
    
    					}
    				}
    			}
    		}
    	}
    	return -1;
    }
    
    
    int main()
    {
    	int T;
    	cin>>T;
    	while (T--)
    	{
    		cin>>n>>m;
    		memset(visited, 0, sizeof(visited));
    		for (int i = 0; i<n; i++)
    		{
    			for (int j = 0; j<m; j++)
    			{
    				cin>>map[i][j];
    				boxStart.innerMap[i][j] = map[i][j];
    				if (map[i][j] == 2)//箱子起始
    				{
    					boxStart.x = i;
    					boxStart.y = j;
    					boxStart.step = 0;
    				}
    			}
    		}
    		cout<<BoxBFS()<<endl;
    	}
    	return 0;
    }
    


  • 相关阅读:
    Android应用签名
    Win7环境下TreeSaver编译环境的搭配
    TreeSaver 使用教程整理——Step 4: Using a Title Figure
    使用jquery获取父元素或父节点的方法
    IIS 错误代码分析手册
    敏捷开发 规范
    Asp.net中时间格式化的几种方法
    在Oracle中使用Guid
    jquery 当前时间
    JQuery一种取同级值的方式 比如你在GridView中如下
  • 原文地址:https://www.cnblogs.com/riskyer/p/3275676.html
Copyright © 2011-2022 走看看