【HDOJ】4347 The Closest M Points

居然是KD解。

  1 /* 4347 */
  2 #include <iostream>
  3 #include <sstream>
  4 #include <string>
  5 #include <map>
  6 #include <queue>
  7 #include <set>
  8 #include <stack>
  9 #include <vector>
 10 #include <deque>
 11 #include <algorithm>
 12 #include <cstdio>
 13 #include <cmath>
 14 #include <ctime>
 15 #include <cstring>
 16 #include <climits>
 17 #include <cctype>
 18 #include <cassert>
 19 #include <functional>
 20 #include <iterator>
 21 #include <iomanip>
 22 using namespace std;
 23 //#pragma comment(linker,"/STACK:102400000,1024000")
 24
 25 #define sti                set<int>
 26 #define stpii            set<pair<int, int> >
 27 #define mpii            map<int,int>
 28 #define vi                vector<int>
 29 #define pii                pair<int,int>
 30 #define vpii            vector<pair<int,int> >
 31 #define rep(i, a, n)     for (int i=a;i<n;++i)
 32 #define per(i, a, n)     for (int i=n-1;i>=a;--i)
 33 #define clr                clear
 34 #define pb                 push_back
 35 #define mp                 make_pair
 36 #define fir                first
 37 #define sec                second
 38 #define all(x)             (x).begin(),(x).end()
 39 #define SZ(x)             ((int)(x).size())
 40 #define lson            l, mid, rt<<1
 41 #define rson            mid+1, r, rt<<1|1
 42
 43 int id, n, m, K;
 44
 45 typedef struct node_t {
 46     int x[5];
 47
 48     friend bool operator< (const node_t& a, const node_t& b) {
 49         return a.x[id] < b.x[id];
 50     }
 51
 52     double Distance(const node_t& a) {
 53         __int64 ret = 0;
 54
 55         rep(i, 0, K)
 56             ret += 1LL*(a.x[i]-x[i])*(a.x[i]-x[i]);
 57
 58         return ret;
 59     }
 60
 61     void print() {
 62         printf("%d", x[0]);
 63         rep(i, 1, K)
 64             printf(" %d", x[i]);
 65         putchar(‘\n‘);
 66     }
 67
 68 } node_t;
 69
 70 typedef struct Node {
 71     __int64 d;
 72     node_t p;
 73
 74     Node() {}
 75     Node(__int64 d, node_t& p):
 76         d(d), p(p) {}
 77
 78     friend bool operator< (const Node& a, const Node& b) {
 79         return a.d < b.d;
 80     }
 81
 82 } Node;
 83
 84 const int maxn = 50005;
 85 node_t nd[maxn];
 86 vector<node_t> ans;
 87
 88 typedef struct KD_tree{
 89     static const int maxd = 5;
 90     static const int maxn = 50005;
 91     node_t P[maxn<<2];
 92     int idx[maxn<<2];
 93     priority_queue<Node> Q;
 94
 95     void Build(int deep, int l, int r, int rt) {
 96         if (l > r)
 97             return ;
 98         idx[rt] = deep % K;
 99         if (l == r) {
100             P[rt] = nd[l];
101             return ;
102         }
103
104         id = idx[rt];
105         int mid = (l + r) >> 1;
106         nth_element(nd+l, nd+mid, nd+r+1);
107         P[rt] = nd[mid];
108         Build(deep+1, l, mid-1, rt<<1);
109         Build(deep+1, mid+1, r, rt<<1|1);
110     }
111
112     void Query(node_t x, int l, int r, int rt) {
113         if (l > r)
114             return ;
115
116         int id = idx[rt];
117         __int64 tmp = x.Distance(P[rt]);
118         if (l == r) {
119             if (SZ(Q) < m) {
120                 Q.push(Node(tmp, P[rt]));
121             } else {
122                 if (tmp < Q.top().d) {
123                     Q.pop();
124                     Q.push(Node(tmp, P[rt]));
125                 }
126             }
127             return ;
128         }
129
130         int mid = (l + r) >> 1;
131
132         if (P[rt].x[id] >= x.x[id]) {
133             Query(x, l, mid-1, rt<<1);
134             if (SZ(Q) < m) {
135                 Q.push(Node(tmp, P[rt]));
136                 Query(x, mid+1, r, rt<<1|1);
137             } else {
138                 if (tmp < Q.top().d) {
139                     Q.pop();
140                     Q.push(Node(tmp, P[rt]));
141                 }
142                 if (1LL*(x.x[id]-P[rt].x[id])*(x.x[id]-P[rt].x[id]) < Q.top().d) {
143                     Query(x, mid+1, r, rt<<1|1);
144                 }
145             }
146         } else {
147             Query(x, mid+1, r, rt<<1|1);
148             if (SZ(Q) < m) {
149                 Q.push(Node(tmp, P[rt]));
150                 Query(x, l, mid-1, rt<<1);
151             } else {
152                 if (tmp < Q.top().d) {
153                     Q.pop();
154                     Q.push(Node(tmp, P[rt]));
155                 }
156                 if (1LL*(x.x[id]-P[rt].x[id])*(x.x[id]-P[rt].x[id]) < Q.top().d) {
157                     Query(x, l, mid-1, rt<<1);
158                 }
159             }
160         }
161     }
162
163     void Dump() {
164         ans.clr();
165         while (!Q.empty()) {
166             ans.pb(Q.top().p);
167             Q.pop();
168         }
169     }
170 } KD_tree;
171
172 KD_tree kd;
173
174 void solve() {
175     int q, sz;
176     node_t p;
177
178     kd.Build(0, 0, n-1, 1);
179     scanf("%d", &q);
180     while (q--) {
181         rep(j, 0, K)
182             scanf("%d", &p.x[j]);
183         scanf("%d", &m);
184         kd.Query(p, 0, n-1, 1);
185         kd.Dump();
186         sz = SZ(ans);
187         printf("the closest %d points are:\n", m);
188         per(i, 0, sz) {
189             ans[i].print();
190         }
191     }
192 }
193
194 int main() {
195     ios::sync_with_stdio(false);
196     #ifndef ONLINE_JUDGE
197         freopen("data.in", "r", stdin);
198         freopen("data.out", "w", stdout);
199     #endif
200
201     while (scanf("%d %d", &n, &K)!=EOF) {
202         rep(i, 0, n)
203             rep(j, 0, K)
204                 scanf("%d", &nd[i].x[j]);
205         solve();
206     }
207
208     #ifndef ONLINE_JUDGE
209         printf("time = %d.\n", (int)clock());
210     #endif
211
212     return 0;
213 }

数据发生器。

 1 from copy import deepcopy
 2 from random import randint, shuffle
 3 import shutil
 4 import string
 5
 6
 7 def GenDataIn():
 8     with open("data.in", "w") as fout:
 9         t = 10
10         bound = 10**5
11         for tt in xrange(t):
12             n = randint(100, 200)
13             k = randint(1, 5)
14             fout.write("%d %d\n" % (n, k))
15             for i in xrange(n):
16                 L = []
17                 for j in xrange(k):
18                     x = randint(-1000, 1000)
19                     L.append(x)
20                 fout.write(" ".join(map(str, L)) + "\n")
21             q = randint(20, 30)
22             fout.write("%d\n" % (q))
23             for qq in xrange(q):
24                 L = []
25                 for j in xrange(k):
26                     x = randint(-1000, 1000)
27                     L.append(x)
28                 fout.write(" ".join(map(str, L)) + "\n")
29                 m = randint(1, 10)
30                 fout.write("%d\n" % (m))
31
32
33 def MovDataIn():
34     desFileName = "F:\eclipse_prj\workspace\hdoj\data.in"
35     shutil.copyfile("data.in", desFileName)
36
37
38 if __name__ == "__main__":
39     GenDataIn()
40     MovDataIn()
时间: 2024-10-05 05:01:46

【HDOJ】4347 The Closest M Points的相关文章

【BZOJ】3053: The Closest M Points(kdtree)

http://www.lydsy.com/JudgeOnline/problem.php?id=3053 本来是1a的QAQ.... 没看到有多组数据啊.....斯巴达!!!!!!!!!!!!!!!!! 本题裸的kdtree,比上一题还要简单...................................... 对于当前点,判断进入左或右子树,然后看答案是否能过分割线..如果能,进入右或左子树.........并且如果答案个数小于k,也要进入.. 然后就浪吧........... #inc

【kd-tree】bzoj3053 The Closest M Points

同p2626.由于K比较小,所以不必用堆. #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> using namespace std; typedef double db; #define N 50001 #define INF 2147483647.0 #define KD 5//ά¶ÈÊý int qp[KD]; int n,root,kd,K; int dn;

【HDOJ】4956 Poor Hanamichi

基本数学题一道,看错位数,当成大数减做了,而且还把方向看反了.所求为最接近l的值. 1 #include <cstdio> 2 3 int f(__int64 x) { 4 int i, sum; 5 6 i = sum = 0; 7 while (x) { 8 if (i & 1) 9 sum -= x%10; 10 else 11 sum += x%10; 12 ++i; 13 x/=10; 14 } 15 return sum; 16 } 17 18 int main() { 1

【HDOJ】1099 Lottery

题意超难懂,实则一道概率论的题目.求P(n).P(n) = n*(1+1/2+1/3+1/4+...+1/n).结果如果可以除尽则表示为整数,否则表示为假分数. 1 #include <cstdio> 2 #include <cstring> 3 4 #define MAXN 25 5 6 __int64 buf[MAXN]; 7 8 __int64 gcd(__int64 a, __int64 b) { 9 if (b == 0) return a; 10 else return

【HDOJ】2844 Coins

完全背包. 1 #include <stdio.h> 2 #include <string.h> 3 4 int a[105], c[105]; 5 int n, m; 6 int dp[100005]; 7 8 int mymax(int a, int b) { 9 return a>b ? a:b; 10 } 11 12 void CompletePack(int c) { 13 int i; 14 15 for (i=c; i<=m; ++i) 16 dp[i]

【HDOJ】3509 Buge&#39;s Fibonacci Number Problem

快速矩阵幂,系数矩阵由多个二项分布组成.第1列是(0,(a+b)^k)第2列是(0,(a+b)^(k-1),0)第3列是(0,(a+b)^(k-2),0,0)以此类推. 1 /* 3509 */ 2 #include <iostream> 3 #include <string> 4 #include <map> 5 #include <queue> 6 #include <set> 7 #include <stack> 8 #incl

【HDOJ】1818 It&#39;s not a Bug, It&#39;s a Feature!

状态压缩+优先级bfs. 1 /* 1818 */ 2 #include <iostream> 3 #include <queue> 4 #include <cstdio> 5 #include <cstring> 6 #include <cstdlib> 7 #include <algorithm> 8 using namespace std; 9 10 #define MAXM 105 11 12 typedef struct {

【HDOJ】2424 Gary&#39;s Calculator

大数乘法加法,直接java A了. 1 import java.util.Scanner; 2 import java.math.BigInteger; 3 4 public class Main { 5 public static void main(String[] args) { 6 Scanner cin = new Scanner(System.in); 7 int n; 8 int i, j, k, tmp; 9 int top; 10 boolean flag; 11 int t

【HDOJ】2425 Hiking Trip

优先级队列+BFS. 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <queue> 5 using namespace std; 6 7 #define MAXN 25 8 9 typedef struct node_st { 10 int x, y, t; 11 node_st() {} 12 node_st(int xx, int yy, int tt)