历届试题 邮局

@ 蓝桥杯 练习系统 历届试题 PREV-24

资源限制

时间限制:1.0s 内存限制:256.0MB


问题描述

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

现在给出了m个备选的邮局,请从中选出k个来,使得村民到自己家最近的邮局的距离和最小。其中两点之间的距离定义为两点之间的直线距离。


输入格式

输入的第一行包含三个整数n, m, k,分别表示村民的户数、备选的邮局数和要建的邮局数。
接下来n行,每行两个整数x, y,依次表示每户村民家的坐标。
接下来m行,每行包含两个整数x, y,依次表示每个备选邮局的坐标。
在输入中,村民和村民、村民和邮局、邮局和邮局的坐标可能相同,但你应把它们看成不同的村民或邮局。


输出格式

输出一行,包含k个整数,从小到大依次表示你选择的备选邮局编号。(备选邮局按输入顺序由1到m编号)


测试样例1

Input:
5 4 2
0 0
2 0
3 1
3 3
1 1
0 1
1 0
2 1
3 2

Output:
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。


ACcode:

import java.io.IOException;
import java.io.InputStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.*;

public class Main {
    
    

    static int n, m, k, selected[];
    static float min, table[][];
    static Node[] home;

    public static void main(String[] args) {
    
    
        InputReader in = new InputReader(System.in, " ");
        n = in.nextInt(); m = in.nextInt(); k = in.nextInt();
        min = Float.MAX_VALUE;
        table = new float[m][n];
        selected = new int[k];
        home = new Node[n];
        for (int i = 0; i < n; i++)
            home[i] = new Node(in.nextInt(), in.nextInt());
        for (int k = 0, x, y; k < m; k++) {
    
    
            x = in.nextInt();
            y = in.nextInt();
            for (int i = 0; i < n; i++)
                table[k][i] = (float)Math.sqrt(squa(home[i].x - x) + squa(home[i].y - y));
        }
        float[] sum = new float[n];
        Arrays.fill(sum, Float.MAX_VALUE);
        LinkedList<Integer> select = new LinkedList();
        dfs(0, 0, sum, select);
        for (int i = 0; i < k; i++) System.out.print(selected[i] + " ");
    }

    static Set<Integer> set = new HashSet();
    static void dfs(int cnt, int cur, float[] sum, LinkedList<Integer> select) {
    
    
        if (n - cur + cnt < k) return;
        if (cnt == k) {
    
    
            float s = 0;
            for (int i = 0; i < n; i++) s += sum[i];
            if (s < min) {
    
    
                min = s;
                Iterator<Integer> se = select.iterator();
                for (int i = 0; i < k; i++)
                    selected[i] = se.next() + 1;
            }
        } else if (cur < m){
    
    
            float[] tmp = new float[n];
            System.arraycopy(sum, 0, tmp, 0, n);
            dfs(cnt, cur + 1, sum, select);
            if (set.contains(cur)) return;
            boolean flag = false;
            for (int i = 0; i < n; i++)
                if (table[cur][i] < tmp[i]) {
    
    
                    flag = true;
                    tmp[i] = table[cur][i];
                }
            if (flag) {
    
    
                select.add(cur);
                dfs(cnt + 1, cur + 1, tmp, select);
                select.removeLast();
            } else set.add(cur);
        }
    }

    static int squa(int x) {
    
     return x * x; }

    static class Node {
    
    

        int x, y;

        Node(int x, int y) {
    
    
            this.x = x;
            this.y = y;
        }
    }

    static class InputReader {
    
    

        BufferedReader read;
        StringTokenizer tok;
        String delimiters;

        InputReader(InputStream in) {
    
     this(in, " \n\t\r\f"); }

        InputReader(InputStream in, String delimiters) {
    
    
            this.read = new BufferedReader(new InputStreamReader(in));
            this.tok = new StringTokenizer("", this.delimiters = delimiters);
        }

        String next() {
    
    
            while (!tok.hasMoreTokens())
                try {
    
    
                    tok = new StringTokenizer(read.readLine(), delimiters);
                } catch (IOException e) {
    
     }
            return tok.nextToken();
        }

        int nextInt() {
    
     return Integer.parseInt(next()); }
    }
}

倒也不是多复杂的题,但不修剪一下节点内存会超限


遇事不决先枚举

import java.io.IOException;
import java.io.InputStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.*;

public class Main {
    
    

    static int n, m, k, selected[];
    static double min, table[][];
    static Node[] home;

    public static void main(String[] args) {
    
    
        InputReader in = new InputReader(System.in, " ");
        n = in.nextInt(); m = in.nextInt(); k = in.nextInt();
        min = Double.MAX_VALUE;
        table = new double[m][n];
        selected = new int[k];
        home = new Node[n];
        for (int i = 0; i < n; i++)
            home[i] = new Node(in.nextInt(), in.nextInt());
        for (int k = 0, x, y; k < m; k++) {
    
    
            x = in.nextInt();
            y = in.nextInt();
            for (int i = 0; i < n; i++)
                table[k][i] = Math.sqrt(squa(home[i].x - x) + squa(home[i].y - y));
        }
        double[] sum = new double[n];
        Arrays.fill(sum, Double.MAX_VALUE);
        LinkedList<Integer> select = new LinkedList();
        dfs(0, 0, sum, select);
        for (int i = 0; i < k; i++) System.out.print(selected[i] + " ");
    }

    static void dfs(int cnt, int cur, double[] sum, LinkedList<Integer> select) {
    
    
        if (cnt == k) {
    
    
            double s = 0;
            for (int i = 0; i < n; i++) s += sum[i];
            if (s < min) {
    
    
                min = s;
                Iterator<Integer> se = select.iterator();
                for (int i = 0; i < k; i++)
                    selected[i] = se.next() + 1;
            }
        } else if (cur < m){
    
    
            double[] tmp = new double[n];
            System.arraycopy(sum, 0, tmp, 0, n);
            for (int i = 0; i < n; i++)
                if (table[cur][i] < tmp[i]) tmp[i] = table[cur][i];
            select.add(cur);
            dfs(cnt + 1, cur + 1, tmp, select);
            select.removeLast();
            dfs(cnt, cur + 1, sum, select);
        }
    }

    static int squa(int x) {
    
     return x * x; }

    static class Node {
    
    

        int x, y;

        Node(int x, int y) {
    
    
            this.x = x;
            this.y = y;
        }
    }

    static class InputReader {
    
    

        BufferedReader read;
        StringTokenizer tok;
        String delimiters;

        InputReader(InputStream in) {
    
     this(in, " \n\t\r\f"); }

        InputReader(InputStream in, String delimiters) {
    
    
            this.read = new BufferedReader(new InputStreamReader(in));
            this.tok = new StringTokenizer("", this.delimiters = delimiters);
        }

        String next() {
    
    
            while (!tok.hasMoreTokens())
                try {
    
    
                    tok = new StringTokenizer(read.readLine(), delimiters);
                } catch (IOException e) {
    
     }
            return tok.nextToken();
        }

        int nextInt() {
    
     return Integer.parseInt(next()); }
    }
}

在这里插入图片描述
434mb 和 256mb 差的属实有点多

不过该题并没有要求精度输出距离合,改用 float试试
在这里插入图片描述
还差点意思

static void dfs(int cnt, int cur, float[] sum, LinkedList<Integer> select) {
    
    
        if (n - cur + cnt < k) return;
        if (cnt == k) {
    
    
            float s = 0;
            for (int i = 0; i < n; i++) s += sum[i];
            if (s < min) {
    
    
                min = s;
                Iterator<Integer> se = select.iterator();
                for (int i = 0; i < k; i++)
                    selected[i] = se.next() + 1;
            }
        } else if (cur < m){
    
    
            float[] tmp = new float[n];
            boolean flag = false;
            System.arraycopy(sum, 0, tmp, 0, n);
            for (int i = 0; i < n; i++)
                if (table[cur][i] < tmp[i]) {
    
    
                    flag = true;
                    tmp[i] = table[cur][i];
                }
            if (flag) {
    
    
                select.add(cur);
                dfs(cnt + 1, cur + 1, tmp, select);
                select.removeLast();
            }
            dfs(cnt, cur + 1, sum, select);
        }
    }

在这里插入图片描述
我就纳闷了,不能给点反馈?

猜你喜欢

转载自blog.csdn.net/qq_43449564/article/details/108818689