zoukankan      html  css  js  c++  java
  • 农夫过河问题

    视频教程地址:https://www.bilibili.com/video/av12642530/#page=19

    问题:

    //人狼菜羊过河问题
    //==============================================================
    #include<iostream>
    #include<vector>
    #include<queue>
    
    using namespace std;
    
    bool farmer(int status)  //获取每个角色的位置,0表示在起始岸,1表示在目标岸
    {
    	return ((status & 0x08) != 0);
    }
    bool wolf(int status)
    {
    	return ((status & 0x04) != 0);
    }
    bool cabbage(int status)
    {
    	return ((status & 0x02) != 0);
    }
    bool goat(int status)
    {
    	return ((status & 0x01) != 0);
    }
    
    
    bool safe(int status)  //判断当前起始岸状态是否安全
    {
    	if ((goat(status) == cabbage(status)) &&
    		(goat(status) != farmer(status)))
    		return false;
    	if ((goat(status) == wolf(status)) &&
    		(goat(status) != farmer(status)))
    		return false;
    	return true;
    }
    
    int main()
    {
    	int movers , status , newstatus;  //movers表示每次过河,人要携带的角色(包括人只身一人过河),值为1表示这个角色发生了一次过河行动
    	//status表示起始岸状态,初始为0000,顺序为人狼菜羊,newstatus表示中间可到达状态
    	vector<int> route(16, -1);  //,顺序表,存储已经访问过的状态(访问过就不能再访问了)
    	queue<int> moveTo;  //存储可以安全到达的中间状态
    	moveTo.push(0x00);  //0000是起始岸的开始状态,四位分别代表人狼羊菜
    	route[0] = 0;  //route第一位存储0,表示已经访问过,-1表示没有访问过
    
    	while (!moveTo.empty() && route[15] == -1)
    	{
    		status = moveTo.front();
    		moveTo.pop();
    		for (movers = 1; movers <= 8; movers <<= 1)  //要携带的角色
    		{
    			if (farmer(status) == (bool)(status & movers))  //要携带的角色必须和人在同一侧
    			{
    				newstatus = status ^ (0x08 | movers);  //这里的按位异或操作实现了渡过去和返回的操作
    				if (safe(newstatus) && (route[newstatus] == -1))  //状态是否安全
    				{
    					route[newstatus] = status;
    					moveTo.push(newstatus);
    				}
    			}
    		}
    	}
    
    	if (route[15] != -1)  //反向打印出结果
    	{
    		cout << "The reverse path is:" << endl;
    		for (int status = 15; status >= 0; status = route[status])
    		{
    			cout << "The status is :" << status << endl;
    			if (status == 0) break;
    		}
    	}
    	else
    		cout << "No solution." << endl;
    	while(1);
    }

    总结一下:在解决这道问题时,首先是问题抽象(找出题目中的约束条件),再而是数据抽象(找出合适的数据结构来表示题目中的各种状态),最后将约束条件和数据结构结合在一起得到最终的算法

    上面的用按位异或实现渡河和返回的操作很精髓~

  • 相关阅读:
    请朋友做事,须以名誉为限,为朋友做事,亦须以名誉为限
    这世上总有一些人记得你,关注着你,牵挂着你
    杏花春雨已不再,牧童遥指已不再,剑门细雨渭城轻尘也都已不再
    如果要你做鲁滨逊,你会选第三型还是第二型的朋友做“礼拜五”呢
    人类最不能伤害的就是自尊
    单靠理论和教训是无济于事的
    交真朋友已是件比较奢侈的事儿
    他一定是一个懂生活、懂人生,爱自己、爱别人的人
    国子监,就是从前的大学
    只有把理想和现实有机结合起来,才有可能成为一个成功之人
  • 原文地址:https://www.cnblogs.com/zf-blog/p/7878080.html
Copyright © 2011-2022 走看看