A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

© 小歪 中级黑马   /  2014-4-9 09:08  /  1191 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 小歪 于 2014-4-9 09:11 编辑

邮局——————>算法分析

   C村住着n户村民,由于交通闭塞,C村的村民只能通过信件与外界交流。
   为了方便村民们发信,C村打算在C村建设k个邮局,这样每户村民可以去离自己家最近的邮局发信。
    现在给出了m个备选的邮局,请从中选出k个来,使得村民到自己家最近的邮局的距离和最小。
    其中两点之间的距离定义为两点之间的直线距离。
【输入格式】
    输入的第一行包含三个整数n, m, k,分别表示村民的户数、备选的邮局数和要建的邮局数。
    接下来n行,每行两个整数x, y,依次表示每户村民家的坐标。
    接下来m行,每行包含两个整数x, y,依次表示每个备选邮局的坐标。
    在输入中,村民和村民、村民和邮局、邮局和邮局的坐标可能相同,
    但你应把它们看成不同的村民或邮局。
【输出格式】
    输出一行,包含k个整数,从小到大依次表示你选择的备选邮局编号。
    (备选邮局按输入顺序由1m编号)
【样例输入】
5 4 2
0 0
2 0
3 1
3 3
1 1
0 1  
1 0   
2 1   
3 2   
【样例输出】
2 3
      
       分析题目知道,此题要求在输入的m个邮局坐标求出离n个用户家距离和最近的k个坐标编号,并且有严格的输入输出要求。
两点之间线段最短:

利用此公式,代码如下:

  1. <FONT color=#000000>package ClassPackage;

  2. import java.io.BufferedReader;
  3. import java.io.InputStreamReader;

  4. public class Test19 {
  5. public static void main(String args[])throws Exception
  6. {
  7. //输入n,m,k的值,并分别放入num[0]、num[1]、num[2]中
  8. BufferedReader buf =new BufferedReader(new InputStreamReader(System.in));
  9. String str[]=buf.readLine().split(" ");
  10. int num[]=new int[str.length];
  11. int i;
  12. for(i=0;i<num.length;i++)
  13. {
  14. num[i]=Integer.parseInt(str[i]);
  15. }

  16. //定义居民坐标存放地址
  17. int resident[][]=new int[num[0]][2];
  18. //定义邮局坐标存放地址
  19. int post[][]=new int[num[1]][2];

  20. //输入n组用户坐标
  21. for(i=0;i<num[0];i++)
  22. {
  23. String temp[]=buf.readLine().split(" ");
  24. resident[i][0]=Integer.parseInt(temp[0]);
  25. resident[i][1]=Integer.parseInt(temp[1]);
  26. }

  27. //输入m组邮局坐标
  28. for(i=0;i<num[1];i++)
  29. {
  30. String temp[]=buf.readLine().split(" ");
  31. post[i][0]=Integer.parseInt(temp[0]);
  32. post[i][1]=Integer.parseInt(temp[1]);
  33. }

  34. //分别计算出m组邮局到n组居民间的各自距离和,放入sum中
  35. int sum[]=new int[num[1]];
  36. for(i=0;i<num[1];i++)
  37. {
  38. for(int j=0;j<num[0];j++)
  39. {
  40. sum[i]+=Math.sqrt(Math.pow(resident[j][0]-post[i][0],2)+Math.pow(resident[j][1]-post[i][1],2));
  41. }
  42. }

  43. int temp1,temp2;
  44. //由于题目要求备选邮局按输入顺序由1到m编号,将编号保存在flag[]中
  45. int flag[]=new int[num[1]];
  46. for(i=0;i<flag.length;i++)
  47. flag[i]=i+1;

  48. //要求输出距离和最短的前K个邮局编号,所以在此由小到大排序,并对应各自的编号
  49. for(i=0;i<sum.length-1;i++)
  50. for(int j=i+1;j<sum.length;j++)
  51. {
  52. if(sum[i]>sum[j])
  53. {
  54. temp2=flag[i];
  55. flag[i]=flag[j];
  56. flag[j]=temp2;

  57. temp1=sum[i];
  58. sum[i]=sum[j];
  59. sum[j]=temp1;
  60. }
  61. }

  62. /*
  63. 此时已经获得K个邮局最短距离和,但是在输出编号时也是由小到大输出的,所以
  64. 我们需将K个编号也进行由小到大排序
  65. */
  66. for(i=0;i<num[2]-1;i++)
  67. {
  68. for(int j=i+1;j<num[2];j++)
  69. {
  70. if(flag[i]>flag[j])
  71. {
  72. temp2=flag[i];
  73. flag[i]=flag[j];
  74. flag[j]=temp2;
  75. }

  76. }

  77. }
  78. //输出距离和最短的k个编号
  79. for(i=0;i<num[2];i++)
  80. System.out.print(flag[i]+" ");
  81. System.out.println();
  82. }

  83. }
  84. </FONT>
复制代码

运行结果测试:

您需要登录后才可以回帖 登录 | 加入黑马