去哪儿第一题怎么做?
发布于 2017-10-11 10:20 3147 次浏览 0 赞 来自 笔试面试  

就是“最少转机”题目,看上去就是用图结构实现的,不过代码不太会,求大神指点

9 条回复

还没考完就问,不大合适吧

2017-10-11 10:27

作图的问题首先我们应该用邻接矩阵或者二维数组来存取顶点之间的关系。

广度优先搜索需要用队列来存储每次扩展的关系。

首先将1号城市入队,通过1号城市我们可以扩展出2号和3号城市,2号城市又可以扩展出3号城市和4号城市。由于3号城市已经在队列中,所以只需要将四号城市入队。

接下来3号城市又可以扩展处4号城市和5号城市,因为4号城市已经在队列中,所以只需要将5号城市入队。此时已经找到5号城市,那么算法结束。


2017-10-11 10:49
coder_yYpE1vJ5 回复 coder_MHQN499K

我是这样做的为啥ac0呀

2017-10-11 10:50

二维数组,递归的深度优先搜索

2017-10-11 11:05

var t = 7;

    var group = ['2.1.4','3.1.4','4.5.7','2.5.7','3.4.6','2.1.8','2.1.0'];

    var key = '*.5.9';

//    var key = '*.*.6';

    function getNew(t,group,key){

        group.sort(function(a,b){  //版本号有小到大排序

            var aa = a.split('.'),

                bb = b.split('.');

            if(aa[0] > bb[0]){

                return 1;

            }else if(aa[0] == bb[0]){

                if(aa[1] > bb[1]){

                    return 1;

                }else if(aa[1] == bb[1]){

                    if(aa[2] > bb[2]){

                        return 1;

                    }else{

                        return 0;

                    }

                }else{

                    return 0;

                }

            }else{

                return 0;

            }

        });


        console.log(group);


        var nums = key.split('.'),reg;

        if(nums[0] == '*'){

            if(nums[1] == '*'){

                if(nums[2] == '*'){

                    return group[t-1];

                }else{

                    reg = new RegExp('^[0-9]{1,3}\.[0-9]{1,3}\.'+nums[2]+'$');

                }

            }else{

                if(nums[2] == '*'){

                    reg = new RegExp('^[0-9]{1,3}\.'+nums[1]+'\.[0-9]{1,3}$');

                }else{

                    reg = new RegExp('^[0-9]{1,3}\.'+nums[1]+'.'+nums[2]+'$');

                }

            }

        }else{

            if(nums[1] == '*'){

                if(nums[2] == '*'){

                    reg = new RegExp('^'+nums[0]+'\.[0-9]{1,3}\.[0-9]{1,3}$');

                }else{

                    reg = new RegExp('^'+nums[0]+'\.[0-9]{1,3}\.'+nums[2]+'$');

                }

            }else{

                if(nums[2] == '*'){

                    reg = new RegExp('^'+nums[0]+'.'+nums[1]+'\.[0-9]{1,3}$');

                }else{

                    reg = new RegExp('^'+nums[0]+'.'+nums[1]+'.'+nums[2]+'$');

                }

            }

        }


        for(var i=t-1;i>=0;i--){

//            console.log(reg);

            console.log(group[i])

          


2017-10-11 11:07

http://dsalgo.openjudge.cn/201409week8/1/

跟这道类似

csdn都有解答,大概就是弄个map,把城市和对应编号塞进去;然后用个二维数组存城市“距离”,同城0,有航线1,没航线设个特别大的值;最后floyd查一遍有没有中转城市,有就“距离”合并,数组里对应的值就是转的次数。

2017-10-11 11:12
package qunarer;

import java.util.Scanner;
public class Main {
    public static int dijkstra(int[][] W1, int start, int end,int n) {  
        boolean[] isLabel = new boolean[n];// 是否标号  
        int[] indexs = new int[n];// 所有标号的点的下标集合,以标号的先后顺序进行存储,实际上是一个以数组表示的栈  
        int i_count = -1;//栈的顶点  
        int[] distance = W1[start].clone();// v0到各点的最短距离的初始值  
        int index = start;// 从初始点开始  
        int presentShortest = 0;//当前临时最短距离  
 
        indexs[++i_count] = index;// 把已经标号的下标存入下标集中  
        isLabel[index] = true;  
          
        while (i_count<W1[0].length) {  
            // 第一步:标号v0,即w[0][0]找到距离v0最近的点  
 
            int min = Integer.MAX_VALUE;  
            for (int i = 0; i < distance.length; i++) {  
                if (!isLabel[i] && distance[i] != -1 && i != index) {  
                    // 如果到这个点有边,并且没有被标号  
                    if (distance[i] < min) {  
                        min = distance[i];  
                        index = i;// 把下标改为当前下标  
                    }  
                }  
            }  
            if (index == end) {//已经找到当前点了,就结束程序  
                break;  
            }  
            isLabel[index] = true;//对点进行标号  
            indexs[++i_count] = index;// 把已经标号的下标存入下标集中  
            if (W1[indexs[i_count - 1]][index] == -1 
                    || presentShortest + W1[indexs[i_count - 1]][index] > distance[index]) {  
                // 如果两个点没有直接相连,或者两个点的路径大于最短路径  
                presentShortest = distance[index];  
            } else {  
                presentShortest += W1[indexs[i_count - 1]][index];  
            }  
 
            // 第二步:将distance中的距离加入vi  
            for (int i = 0; i < distance.length; i++) {  
                // 如果vi到那个点有边,则v0到后面点的距离加  
                if (distance[i] == -1 && W1[index][i] != -1) {// 如果以前不可达,则现在可达了  
                    distance[i] = presentShortest + W1[index][i];  
                } else if (W1[index][i] != -1 
                        && presentShortest + W1[index][i] < distance[i]) {  
                    // 如果以前可达,但现在的路径比以前更短,则更换成更短的路径  
                    distance[i] = presentShortest + W1[index][i];  
                }  
 
            }  
        }  
        //如果全部点都遍历完,则distance中存储的是开始点到各个点的最短路径  
        return distance[end];  
    }
	public static void main(String args[]){
		Scanner s=new Scanner(System.in);
		Main mth=new Main();
		String firstLine=s.nextLine();
		String first[]=firstLine.split(" ", 4);
		int n=Integer.parseInt(first[0]);
		int m=Integer.parseInt(first[1]);
		String start=first[2];
		int startindex=-1;
		String end=first[3];
		int endindex=-1;
		String city="";
		String citys[]=new String[n];
		String Line[][]=new String[m][2];
		int count=0;
		for(int i=0;i<m;i++){
			String inline=s.nextLine();
			String temp[]=inline.split(" ", 2);
			for(int j=0;j<2;j++){
				Line[i][j]=temp[j];
				if(!city.contains(temp[j])){
					city=city+temp[j]+" ";
					citys[count]=temp[j];
					count++;
				}
			}
		}
//		for(int i=0;i<count;i++){
//		System.out.println(citys[i]+" ");
//		}
		//根据citys+Line构造邻接矩阵
		int mat[][]=new int[n][n];
		for(int i=0;i<n;i++){
			if(start.equals(citys[i])){
				startindex=i;
			}
			if(end.equals(citys[i])){
				endindex=i;
			}
			if(startindex!=-1 && endindex!=-1){
				break;
			}
		}
		for(int i=0;i<m;i++){
			int row=-1;
			int col=-1;
			for(int j=0;j<n;j++){
				if(Line[i][0].equals(citys[j])){
					row=j;
				}
				if(Line[i][1].equals(citys[j])){
					col=j;
				}
				if(row!=-1 && col!=-1){
					break;
				}
			}
			mat[row][col]=1;
			mat[col][row]=1;
		}
		for(int i=0;i<n;i++){
			for(int j=0;j<n;j++){
				if(mat[i][j]!=1){
					mat[i][j]=-1;
				}
				//System.out.print(mat[i][j]+"    ");
			}
			//System.out.println();
		}
		System.out.println(mth.dijkstra(mat, startindex, endindex,n));
	}
}


2017-10-11 14:37
coder_MHQN499K 回复 coder_yYpE1vJ5

import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.TreeMap;

/*

5 5 luoyang jinling changan luoyang luoyang jiankang luoyang langye jiankang langye jiankang jinling

  • */ public class qunar1 {

    public static class node{ Integer x; //城市序号 Integer s; //转机次数

    public node(int x, int s){
    	this.x = x;
    	this.s = s;
    }
    

    }

    static Map<String, Integer> subscript = new TreeMap<>(); //记录地点和序号的关系 public static int getSub(String s){ return subscript.get(s); }

    public static void main(String[] args) throws IOException {

    Set<String> set = new HashSet<>();	//记录不重复的地点
    ArrayList<String[]> arrList = new ArrayList<>(); //记录不同的航线
    ArrayList<qunar1.node> que = new ArrayList<>(); //用一个数组代替队列,遍历图
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
     String[] str = br.readLine().split(" ");
     int n = Integer.parseInt(str[0]);
     int m = Integer.parseInt(str[1]);
     int[][] e = new int[2*n][2*n];
     int[] book = new int[2*n];
     String startStr = str[2];
     String endStr = str[3];
    
     String str2 = br.readLine();
     while(str2!=null){
         String[] arr = str2.trim().split(" ");
         arrList.add(arr);
         set.add(arr[0]);
         set.add(arr[1]);
         str2 = br.readLine();
     }
     int sub = 1;
     for(String s:set){
     	subscript.put(s,sub);
     	sub++;
     }
     int start = getSub(startStr);
     int end = getSub(endStr);
     
     for(Map.Entry<String, Integer> entry :subscript.entrySet()){
     	System.out.println(entry.getKey()+" "+entry.getValue());
     	node nn = new node(0,0);
     	que.add(nn);
     }
     for(int i=1;i<= n;i++){
     	for(int j = 1;j<=n;j++){
     		if(i == j)
     			e[i][j] = 0;
     		else {
    			e[i][j] = 666666;
    		}
     	}
     }
     for(String[] sss:arrList){
     	e[getSub(sss[0])][getSub(sss[1])] = 1;
     	e[getSub(sss[1])][getSub(sss[0])] = 1;
     	
     }
     
     int head = 0;
     int tail = 1;
     int flag = 0;
     que.set(head, new node(start, 0));//(编号,转机数)
     book[start] = 1;
     
     while(head<tail){
     	int cur = que.get(head).x; //这一步就确定了每一次只能从队列中取出已经存入的点
     	for(int i=1;i <=n;i++){
     		if(e[cur][i] != 666666 && book[i]==0){
     			que.set(tail, new node(i, que.get(head).s+1));
     			tail++;
     			book[i] = 1;
     		}
     		if(que.get(tail-1).x == end){
     			flag = 1;
     		}
     		
     	}
     	if(flag == 1){
     		break;
     	}
     	head++;
     }
     System.out.println("从"+startStr+"到"+endStr+"最少需要转机"+que.get(tail-1).s+"次。");
    

    }

}

2017-10-12 14:38

这是我的代码:

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStreamReader;

import java.util.ArrayList;

import java.util.HashSet;

import java.util.Map;

import java.util.Set;

import java.util.TreeMap;





/*

 * 

 * 

5 5 luoyang jinling

changan luoyang 

luoyang jiankang 

luoyang langye

jiankang langye

jiankang jinling


 * */

public class qunar1 {

public static class node{

Integer x; //城市序号

Integer s; //转机次数

public node(int x, int s){

this.x = x;

this.s = s;

}

}

static Map<String, Integer> subscript = new TreeMap<>(); //记录地点和序号的关系

public static int getSub(String s){

return subscript.get(s);

}

public static void main(String[] args) throws IOException {

Set<String> set = new HashSet<>(); //记录不重复的地点

ArrayList<String[]> arrList = new ArrayList<>(); //记录不同的航线

ArrayList<qunar1.node> que = new ArrayList<>(); //用一个数组代替队列,遍历图

BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

   String[] str = br.readLine().split(" ");

   int n = Integer.parseInt(str[0]);

   int m = Integer.parseInt(str[1]);

   int[][] e = new int[2*n][2*n];

   int[] book = new int[2*n];

   String startStr = str[2];

   String endStr = str[3];


   String str2 = br.readLine();

   while(str2!=null){

       String[] arr = str2.trim().split(" ");

       arrList.add(arr);

       set.add(arr[0]);

       set.add(arr[1]);

       str2 = br.readLine();

   }

   int sub = 1;

   for(String s:set){

    subscript.put(s,sub);

    sub++;

   }

   int start = getSub(startStr);

   int end = getSub(endStr);

   

   for(Map.Entry<String, Integer> entry :subscript.entrySet()){

    System.out.println(entry.getKey()+" "+entry.getValue());

    node nn = new node(0,0);

    que.add(nn);

   }

   for(int i=1;i<= n;i++){

    for(int j = 1;j<=n;j++){

    if(i == j)

    e[i][j] = 0;

    else {

e[i][j] = 666666;

}

    }

   }

   for(String[] sss:arrList){

    e[getSub(sss[0])][getSub(sss[1])] = 1;

    e[getSub(sss[1])][getSub(sss[0])] = 1;

   

   }

   

   int head = 0;

   int tail = 1;

   int flag = 0;

   que.set(head, new node(start, 0));//(编号,转机数)

   book[start] = 1;

   

   while(head<tail){

    int cur = que.get(head).x; //这一步就确定了每一次只能从队列中取出已经存入的点

    for(int i=1;i <=n;i++){

    if(e[cur][i] != 666666 && book[i]==0){

    que.set(tail, new node(i, que.get(head).s+1));

    tail++;

    book[i] = 1;

    }

    if(que.get(tail-1).x == end){

    flag = 1;

    }

   

    }

    if(flag == 1){

    break;

    }

    head++;

   }

   System.out.println("从"+startStr+"到"+endStr+"最少需要转机"+que.get(tail-1).s+"次。");

   

}


}


2017-10-12 14:39
添加回复
回到顶部