花了好多天学习java基础,刚刚才提交了基础测试题,觉得最后一道题挺有意思的,第十题:一位老农带着猫、狗、鱼过河,河边有一条船,每次老农只能带一只动物过河。当老农不和猫狗鱼在一起时,狗会咬猫,猫会吃鱼,当老农和猫狗鱼在一起时,则不会发生这种问题。编程解决猫狗鱼过河问题。有木有同学和我一样的题目,可以一起讨论一下。
想了好久,最后用图论深度优先搜索解决。
思路:假设刚开始渡河的那边 人、猫、鱼、狗各个状态是(用二进制表示):0000,那么成功过河后他们的各个状态是:1111。所以过河问题就是从0000起始状态到1111最终状态的过程,因此总共有16中状态。然后把每一种状态看成图的一个结点,把可以连通的结点用有向边连起来,就构成的一个有向图。从0000这个结点遍历(深度优先搜索)图,遍历到1111结点则找到解。
附上代码,仅供参考,可能有错误,望大神指正:
- public class Test10 {
-
- private int[][] maxtri = new int[16][16]; // 邻接矩阵,存储结点是否联通
- private int[][] flag = { { 0, 0 }, { 1, 0 }, { 2, 0 }, { 3, 0 }, { 4, 0 },
- { 5, 0 }, { 6, 0 }, { 7, 0 }, { 8, 0 }, { 9, 0 }, { 10, 0 },
- { 11, 0 }, { 12, 0 }, { 13, 0 }, { 14, 0 }, { 15, 0 } };// 状态是否被访问过的数组
- private Stack stack = new Stack();
-
- /**
- * 得到状态的字符串表示 0000 四位分别代表人 猫 鱼 狗
- * @param x 状态值
- * @return 格式化的字符串
- */
- public String getFormatString(int x) {
- String X = Integer.toBinaryString(x);
- if (X.length() < 4 && X.length() >= 3) {
- X = "0" + X;
- } else if (X.length() < 3 && X.length() >= 2) {
- X = "00" + X;
- } else if (X.length() < 2 && X.length() >= 1) {
- X = "000" + X;
- }
- return X;
- }
- /**
- * 判断两个结点是否连通
- * @param x 前一个结点状态
- * @param y 后一个结点状态
- * @return 连通为1 ,不连通为0
- */
- private boolean isConnected(int x, int y) {
- String X = getFormatString(x);
- String Y = getFormatString(y);
- if (X.charAt(0) == Y.charAt(0))
- return false;
- else {
- if (X.charAt(1) != Y.charAt(1) && X.charAt(2) != Y.charAt(2)
- && X.charAt(3) != Y.charAt(3)) {
- return false;
- }
- else if (X.charAt(1) != Y.charAt(1) && X.charAt(2) != Y.charAt(2)) {
- return false;
- }
- else if (X.charAt(1) != Y.charAt(1) && X.charAt(3) != Y.charAt(3)) {
- return false;
- }
- else if (X.charAt(2) != Y.charAt(2) && X.charAt(3) != Y.charAt(3)) {
- return false;
- }
- else if (((X.charAt(0) != X.charAt(1)) && (X.charAt(1) != Y.charAt(1)))
- || ((X.charAt(0) != X.charAt(2)) && (X.charAt(2) != Y.charAt(2)))
- || ((X.charAt(0) != X.charAt(3)) && (X.charAt(3) != Y.charAt(3)))) {
- return false;
- }
- return true;
- }
- }
- /**
- * 初始化邻接矩阵
- */
- public void InitMaxtri(){
- for (int i = 0; i <16; i++) {
- for (int j = 0; j < 16; j++) {
- if(isConnected(i, j)){
- maxtri[i][j] = 1;
- }
- else{
- maxtri[i][j] = 0;
- }
- }
- }
- }
- /**
- * 得到与输入节点相连的一个结点
- * @param x
- * @return
- */
- public int getVetex(int x){
- for (int i = 0; i < 16; i++) {
- if(maxtri[x][i] == 1 && flag[i][1] == 0){
- String X = getFormatString(i);
- if((X.charAt(0)!=X.charAt(1)&&X.charAt(1)==X.charAt(3))||
- (X.charAt(0)!=X.charAt(1)&&X.charAt(1)==X.charAt(2))){
- continue;
- }
- else {
- return i;
- }
- }
- }
- return -1;
- }
- /**
- * 深度优先搜索
- */
- public void DFS(){
- stack.push(0);
- flag[0][1]=1;
- while(!stack.isEmpty()){
- if(stack.getTop() == 15){
- break;
- }
- int Vetex = getVetex(stack.getTop());
- if(Vetex==-1){
- try{
- stack.pop();
- }catch(Exception e){
- e.printStackTrace();
- }
- }
- else{
- stack.push(Vetex);
- flag[Vetex][1] = 1;
- }
- }
-
- }
- /**
- * 打印结果
- * @throws Exception
- */
- public void printOrder() throws Exception{
- for(int i=0;i< stack.getLength()-1;i++){
- int x=stack.seekByIndex(i);
- int y=stack.seekByIndex(i+1);
- String X=getFormatString(x);
- String Y=getFormatString(y);
- String type="";
- if(X.charAt(0)=='0'){
- type="过河";
- }
- if(X.charAt(0)=='1'){
- type="回来";
- }
- if(X.charAt(1)!=Y.charAt(1)){
- System.out.println("人带猫"+type);
- }
- else if(X.charAt(2)!=Y.charAt(2)){
- System.out.println("人带鱼"+type);
- }
- else if(X.charAt(3)!=Y.charAt(3)){
- System.out.println("人带狗"+type);
- }
- else{
- System.out.println("人自己"+type);
- }
- }
- }
- public static void main(String[] args) {
- // TODO Auto-generated method stub
- Test10 test = new Test10();
- test.InitMaxtri();
- test.DFS();
- try{
- test.printOrder();
- }catch(Exception e){
- e.printStackTrace();
- }
- }
- /**
- * 数据栈
- * @author daoqin
- */
- public class Stack{
-
- private int[] num;
- private int top;
- public Stack(){
- InitStack();
- }
- public void InitStack(){
- top = -1;
- num = new int[16];
- }
- public int getTop(){
- return num[top];
- }
- public int pop() throws Exception{
- if(top>=0){
- return num[top--];
- }
- else{
- throw new Exception("栈空");
- }
- }
- public void push(int x){
- num[++top]=x;
- }
- public boolean isEmpty(){
- return (top<0);
- }
- public int getLength(){
- return top+1;
- }
- public int seekByIndex(int index)throws Exception{
- if(index < getLength() && index >= 0){
- return num[index];
- }
- else {
- throw new Exception("未找到元素!");
- }
- }
- }
- }
复制代码
|