• Java实现 蓝桥杯 历届试题 邮局


    问题描述
      C村住着n户村民,由于交通闭塞,C村的村民只能通过信件与外界交流。为了方便村民们发信,C村打算在C村建设k个邮局,这样每户村民可以去离自己家最近的邮局发信。

    现在给出了m个备选的邮局,请从中选出k个来,使得村民到自己家最近的邮局的距离和最小。其中两点之间的距离定义为两点之间的直线距离。
    输入格式
      输入的第一行包含三个整数n, m, k,分别表示村民的户数、备选的邮局数和要建的邮局数。
      接下来n行,每行两个整数x, y,依次表示每户村民家的坐标。
      接下来m行,每行包含两个整数x, y,依次表示每个备选邮局的坐标。
      在输入中,村民和村民、村民和邮局、邮局和邮局的坐标可能相同,但你应把它们看成不同的村民或邮局。
    输出格式
      输出一行,包含k个整数,从小到大依次表示你选择的备选邮局编号。(备选邮局按输入顺序由1到m编号)
    样例输入
    5 4 2
    0 0
    2 0
    3 1
    3 3
    1 1
    0 1
    1 0
    2 1
    3 2
    样例输出
    2 4
    数据规模和约定
      对于30%的数据,1<=n<=10,1<=m<=10,1<=k<=5;
      对于60%的数据,1<=m<=20;
      对于100%的数据,1<=n<=50,1<=m<=25,1<=k<=10。

    import java.util.Scanner;
    
    public class Main {
        public static int n, m, k;
        public static double[][] distance;    //distanc[i][j]表示第i个村庄到第j个邮局的直线距离
        public static int[] answer;  //存放最终选中的k个邮局编号
        public static double minSum;   //表示选中k个邮局的最小距离和
        
        public void init() {
            distance = new double[n + 1][m + 1];
            answer = new int[k + 1];
            minSum = Double.MAX_VALUE;
        }
        
        /*
         * 参数count:表示已经选中的邮局个数
         * 参数current:表示DFS目前遍历到的邮局编号
         * 参数minDis:minDis[i]表示村庄i到已选中邮局中的最短距离
         * 参数tempAns:存放目前遍历过程中已经选中的邮局编号
         */
        public void dfs(int count, int current, double[] minDis, int[] tempAns) {
            if(count == k) {  //当已经选中k个邮局时
                double tempSum = 0;
                for(int i = 1;i <= n;i++)
                    tempSum += minDis[i];
                if(tempSum < minSum) {
                    minSum = tempSum;
                    for(int i = 1;i <= k;i++)
                        answer[i] = tempAns[i];
                }
                return;
            } else if(k - count <= m - current && current <= m) { //表示在剩下未选中的邮局个数多于还需要选中的邮局个数
                boolean judge = false;   //用于判断当前选中的邮局current+1是否符合要求
                double[] minDis1 = new double[n + 1];  //用于保存当前minDis数组中值
                for(int i = 1;i <= n;i++)
                    minDis1[i] = minDis[i];
                for(int i = 1;i <= n;i++) {
                    if(minDis[i] > distance[i][current + 1]) {
                        minDis[i] = distance[i][current + 1];
                        judge = true;
                    }
                }
                tempAns[count + 1] = current + 1;
                if(judge == true)  //邮局current + 1符合要求,选中个数加1继续搜索
                    dfs(count + 1, current + 1, minDis, tempAns);
                dfs(count, current + 1, minDis1, tempAns); //直接舍弃邮局current+1,进行下一次搜索
            }
        }
            
        public static void main(String[] args) {
            Main test = new Main();
            Scanner in = new Scanner(System.in);
            n = in.nextInt();
            m = in.nextInt();
            k = in.nextInt();
            test.init();
            double[][] point = new double[n + 1][2];   //存放n个村庄的位置坐标
            for(int i = 1;i <= n;i++) {
                point[i][0] = in.nextDouble();   //村庄横坐标
                point[i][1] = in.nextDouble();   //村庄纵坐标
            }
            for(int j = 1;j <= m;j++) {
                double x = in.nextDouble();      //邮局横坐标
                double y = in.nextDouble();      //邮局纵坐标
                for(int i = 0;i <= n;i++)       //计算1~n村庄到邮局j的直线距离
                    distance[i][j] = Math.sqrt((point[i][0]-x)*(point[i][0]-x) + 
                            (point[i][1]-y)*(point[i][1]-y));
            }
            int[] tempAns = new int[k + 1];
            double[] minDis = new double[n + 1]; //minDis[i]表示第i个村庄到已选中的邮局中的最小距离
            for(int i = 1;i <= n;i++)
                minDis[i] = Double.MAX_VALUE;//初始化第i个村庄到选中邮局中最小距离为最大值
            
            test.dfs(0, 0, minDis,  tempAns);
            for(int i = 1;i <= k;i++)
                System.out.print(answer[i]+" ");
        }
    }
    
  • 相关阅读:
    微信小程序HTTPS
    微信商城-1简介
    va_list
    Event log c++ sample.
    EVENT LOGGING
    Analyze Program Runtime Stack
    unknow table alarmtemp error when drop database (mysql)
    This application has request the Runtime to terminate it in an unusual way.
    How to check if Visual Studio 2005 SP1 is installed
    SetUnhandledExceptionFilter
  • 原文地址:https://www.cnblogs.com/a1439775520/p/13077955.html
Copyright © 2020-2023  润新知