Time Limit: 16000/8000 MS (Java/Others)    Memory Limit: 98304/98304 K (Java/Others)

Total Submission(s): 3520    Accepted Submission(s): 1247

Problem Description
The course of Software Design and Development Practice is objectionable. ZLC is facing a serious problem .There are many points in K-dimensional space .Given a point. ZLC need to find out the closest m points. Euclidean distance is used as the distance metric
between two points. The Euclidean distance between points p and q is the length of the line segment connecting them.In Cartesian coordinates, if p = (p1, p2,..., pn) and q = (q1, q2,..., qn)
are two points in Euclidean n-space, then the distance from p to q, or from q to p is given by:




Can you help him solve this problem?
 
Input
In the first line of the text file .there are two non-negative integers n and K. They denote respectively: the number of points, 1 <= n <= 50000, and the number of Dimensions,1 <= K <= 5. In each of the following n lines there is written k integers, representing
the coordinates of a point. This followed by a line with one positive integer t, representing the number of queries,1 <= t <=10000.each query contains two lines. The k integers in the first line represent the given point. In the second line, there is one integer
m, the number of closest points you should find,1 <= m <=10. The absolute value of all the coordinates will not be more than 10000.

There are multiple test cases. Process to end of file.
 
Output
For each query, output m+1 lines:

The first line saying :”the closest m points are:” where m is the number of the points.

The following m lines representing m points ,in accordance with the order from near to far

It is guaranteed that the answer can only be formed in one ways. The distances from the given point to all the nearest m+1 points are different. That means input like this:

2 2

1 1

3 3

1

2 2

1

will not exist.
 
Sample Input
  1. 3 2
  2. 1 1
  3. 1 3
  4. 3 4
  5. 2
  6. 2 3
  7. 2
  8. 2 3
  9. 1
 
Sample Output
  1. the closest 2 points are:
  2. 1 3
  3. 3 4
  4. the closest 1 points are:
  5. 1 3
 
Author
HIT
 
Source
 

【题解】

kd-tree,虽然不是曼哈顿距离。但是还是能够从曼哈顿距离里面得到启发的。

本来的估价函数的原则是

如果在矩形内就返回0.这点不变。

然后在矩形外就返回到这个矩形的最小曼哈顿距离。现在改成欧几里得距离就可以了。

然后返回这个距离作为估价函数。

取估价函数较小的那个方向更新解就可以了。

前k小的话可以加一个队列维护。因为k最大为10,所以没必要写二分。

具体的看代码吧。

着重看一下估价函数就好。

//数据范围实际上是可以不用定义long long的。但是保险起见。

//k维的并没有什么可怕的。。就是for 0->1变成for 0->k-1

//然后要注意多个维的点的输出最后一个维的坐标后面不能多空格。

【代码】

  1. #include <cstdio>
  2. #include <algorithm>
  3. #include <cstring>
  4.  
  5. using namespace std;
  6.  
  7. const int MAXN = 60000;
  8. const int MAXK_TH = 20;
  9. const long long INF = 4410000000000000000;
  10.  
  11. struct point
  12. {
  13. long long d[5], mi_n[5], ma_x[5];
  14. int l, r;
  15. };
  16.  
  17. struct data2
  18. {
  19. long long dis, d[5];
  20. };
  21.  
  22. int n, k, root, now, k_th;
  23. point t[MAXN], p[MAXN], op;
  24. long long ans;
  25. data2 dl[MAXK_TH];
  26.  
  27. bool cmp(point a, point b)
  28. {
  29. if (a.d[now] < b.d[now])
  30. return true;
  31. return false;
  32. }
  33.  
  34. void push_up(int rt)
  35. {
  36. int l = t[rt].l, r = t[rt].r;
  37. for (int i = 0; i <= k - 1; i++)
  38. {
  39. if (l)
  40. {
  41. t[rt].ma_x[i] = max(t[l].ma_x[i], t[rt].ma_x[i]);
  42. t[rt].mi_n[i] = min(t[l].mi_n[i], t[rt].mi_n[i]);
  43. }
  44. if (r)
  45. {
  46. t[rt].ma_x[i] = max(t[r].ma_x[i], t[rt].ma_x[i]);
  47. t[rt].mi_n[i] = min(t[r].mi_n[i], t[rt].mi_n[i]);
  48. }
  49. }
  50. }
  51.  
  52. int build(int begin, int end, int fx)
  53. {
  54. int m = (begin + end) >> 1;
  55. now = fx;
  56. nth_element(p + begin, p + m, p + end + 1, cmp);
  57. t[m] = p[m];
  58. for (int i = 0; i <= k - 1; i++)
  59. t[m].ma_x[i] = t[m].mi_n[i] = t[m].d[i];
  60. if (begin < m)
  61. t[m].l = build(begin, m - 1, (fx + 1) % k);
  62. if (m < end)
  63. t[m].r = build(m + 1, end, (fx + 1) % k);
  64. push_up(m);
  65. return m;
  66. }
  67.  
  68. void input_data()
  69. {
  70. memset(t, 0, sizeof(t));
  71. for (int i = 1; i <= n; i++)
  72. for (int j = 0; j <= k - 1; j++)
  73. scanf("%lld", &p[i].d[j]);
  74. root = build(1, n, 0);
  75. }
  76.  
  77. long long get_dis(point a, point b)
  78. {
  79. long long temp = 0;
  80. for (int i = 0; i <= k - 1; i++)
  81. temp += (a.d[i] - b.d[i])*(a.d[i] - b.d[i]);
  82. return temp;
  83. }
  84.  
  85. long long sqr(long long x)
  86. {
  87. return x*x;
  88. }
  89.  
  90. long long gujia_min(int rt) //某个子树的估价最小函数
  91. {
  92. long long temp = 0;
  93. for (int i = 0; i <= k - 1; i++)
  94. {
  95. //min(sqr(t[rt].ma_x[i] - op.d[i]), sqr(t[rt].mi_n[i] - op.d[i]));
  96. long long temp1 = op.d[i] - t[rt].ma_x[i];
  97. long long temp2 = t[rt].mi_n[i] - op.d[i];
  98. if (temp1 > 0)
  99. temp += sqr(op.d[i] - t[rt].ma_x[i]);
  100. if (temp2 > 0)
  101. temp += sqr(t[rt].mi_n[i] - op.d[i]);
  102. }
  103. return temp;
  104. }
  105.  
  106. void query_min(int rt)
  107. {
  108. long long dis = get_dis(t[rt], op);
  109. int tempk = k_th;
  110. while (dl[tempk].dis > dis)
  111. {
  112. tempk--;
  113. if (!tempk)
  114. break;
  115. }
  116. if (tempk != k_th) //如果比第k小的还小 就往前找一个合适的位置放进去。
  117. {//然后第k小的就被挤掉 更新了。
  118. for (int i = k_th; i >= tempk + 2; i--)
  119. dl[i] = dl[i - 1];
  120. dl[tempk + 1].dis = dis;
  121. for (int i = 0; i <= k - 1; i++)
  122. dl[tempk + 1].d[i] = t[rt].d[i];
  123. }
  124. long long gl = INF, gr = INF;
  125. int l = t[rt].l, r = t[rt].r;
  126. if (l)
  127. gl = gujia_min(l);
  128. if (r)
  129. gr = gujia_min(r);
  130. if (gl < gr)
  131. {
  132. if (gl < dl[k_th].dis)
  133. query_min(l);
  134. if (gr < dl[k_th].dis)
  135. query_min(r);
  136. }
  137. else
  138. {
  139. if (gr < dl[k_th].dis)
  140. query_min(r);
  141. if (gl < dl[k_th].dis)
  142. query_min(l);
  143. }
  144. }
  145.  
  146. void output_ans()
  147. {
  148. int t;
  149. scanf("%d", &t);
  150. while (t--)
  151. {
  152. for (int i = 0; i <= k - 1; i++)
  153. scanf("%lld", &op.d[i]);
  154. scanf("%d", &k_th);
  155. for (int i = 0; i <= k_th; i++)
  156. dl[i].dis = INF;
  157. ans = INF;
  158. query_min(root);
  159. printf("the closest %d points are:\n", k_th);
  160. for (int i = 1; i <= k_th; i++)
  161. {
  162. for (int j = 0; j <= k - 2; j++)
  163. printf("%lld ", dl[i].d[j]);
  164. printf("%lld\n", dl[i].d[k - 1]);//最后一维的坐标后面不能加空格。
  165. }
  166. }
  167. }
  168.  
  169. int main()
  170. {
  171. //freopen("F:\\rush.txt", "r", stdin);
  172. while (~scanf("%d%d", &n, &k)) //一直好奇前面的波浪号一样的是啥
  173. {
  174. input_data();
  175. output_ans();
  176. }
  177. return 0;
  178. }

【35.43%】【hdu 4347】The Closest M Points的更多相关文章

  1. 【改革春风吹满地 HDU - 2036 】【计算几何-----利用叉积计算多边形的面积】

    利用叉积计算多边形的面积 我们都知道计算三角形的面积时可以用两个邻边对应向量积(叉积)的绝对值的一半表示,那么同样,对于多边形,我们可以以多边形上的一个点为源点,作过该点并且过多边形其他点中的某一个的 ...

  2. 【HDU 2255】奔小康赚大钱 (最佳二分匹配KM算法)

    奔小康赚大钱 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Subm ...

  3. 【二分】【最长上升子序列】HDU 5489 Removed Interval (2015 ACM/ICPC Asia Regional Hefei Online)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5489 题目大意: 一个N(N<=100000)个数的序列,要从中去掉相邻的L个数(去掉整个区间 ...

  4. 【贪心】【模拟】HDU 5491 The Next (2015 ACM/ICPC Asia Regional Hefei Online)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5491 题目大意: 一个数D(0<=D<231),求比D大的第一个满足:二进制下1个个数在 ...

  5. 【动态规划】【二分】【最长上升子序列】HDU 5773 The All-purpose Zero

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5773 题目大意: T组数据,n个数(n<=100000),求最长上升子序列长度(0可以替代任何 ...

  6. 【动态规划】【KMP】HDU 5763 Another Meaning

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5763 题目大意: T组数据,给两个字符串s1,s2(len<=100000),s2可以被解读成 ...

  7. 【归并排序】【逆序数】HDU 5775 Bubble Sort

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5775 题目大意: 冒泡排序的规则如下,一开始给定1~n的一个排列,求每个数字在排序过程中出现的最远端 ...

  8. 【中国剩余定理】【容斥原理】【快速乘法】【数论】HDU 5768 Lucky7

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5768 题目大意: T组数据,求L~R中满足:1.是7的倍数,2.对n个素数有 %pi!=ai  的数 ...

  9. 【规律】【贪心】【数学】HDU 5573 Binary Tree

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5573 题目大意: 从1走到第k层,下一层的数是上一层的数*2或者*2+1,可以选择加上或者减去走的数 ...

随机推荐

  1. Error: org.apache.mahout.math.CardinalityException: Required cardinality 10 but got 30问题解决办法

    问题详情 在运行mahout中kmeans算法时,采取的是其默认输入路径/user/hadoop/testdata 和 默认输出路径/user/hadoop/output. [hadoop@djt00 ...

  2. Ajax : load()

    <body> <input type="button" value="Ajax" /> <div id="box&quo ...

  3. BZOJ2244: [SDOI2011]拦截导弹(CDQ分治,二维LIS,计数)

    Description 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度.并且能够拦截任意速度的导弹,但是以后每一发炮弹都不能高 ...

  4. BZOJ4044: [Cerc2014] Virus synthesis(回文树+DP)

    Description Viruses are usually bad for your health. How about fighting them with... other viruses? ...

  5. (cocos2d-js游戏)測试你的反应速度----------基本逻辑(上)

    游戏玩法:点击開始游戏.等待一个随机时间.然后背景颜色会变(在t1时刻),这时候你须要点击屏幕(在t2时刻),游戏结束.你的反应时间就是天t2-t1. 游戏逻辑: 游戏逻辑非常easy,如上图所看到的 ...

  6. 1.IntelliJ IDEA搭建SpringBoot的小Demo

    转自:http://www.cnblogs.com/weizaibug/p/6657077.html 首先简单介绍下Spring Boot,来自度娘百科:Spring Boot是由Pivotal团队提 ...

  7. VC 常见问题百问

    http://www.cnblogs.com/cy163/archive/2006/06/19/429796.html 经典Vc书 Charles Petzold 的<Programming W ...

  8. 00089_字节输出流OutputStream

    1.字节输出流OutputStream (1)OutputStream此抽象类,是表示输出字节流的所有类的超类.操作的数据都是字节,定义了输出字节流的基本共性功能方法: (2)输出流中定义都是写wri ...

  9. Maven学习总结(18)——深入理解Maven仓库

    一.本地仓库(Local Repository) 本地仓库就是一个本机的目录,这个目录被用来存储我们项目的所有依赖(插件的jar包还有一些其他的文件),简单的说,当你build一个Maven项目的时候 ...

  10. amazeui学习笔记--css(常用组件12)--面板Panel

    amazeui学习笔记--css(常用组件12)--面板Panel 一.总结 1.面板基本样式:默认的 .am-panel 提供基本的阴影和边距,默认边框添加 .am-panel-default,内容 ...