In case of failure

近点查询算法解析
本文深入探讨了在二维平面上寻找最近邻居点的算法,通过构建数据结构来快速定位每个现金机器的最近工作正常点,解决银行ATM故障时客户引导问题。采用优先队列和KD树进行高效查询,讲解了算法实现细节。

In case of failure

http://acm.hdu.edu.cn/showproblem.php?pid=2966

Time Limit: 60000/30000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2843    Accepted Submission(s): 1209


Problem Description
To help their clients deal with faulty Cash Machines, the board of The Planar Bank has decided to stick a label expressing sincere regret and sorrow of the bank about the failure on every ATM. The very same label would gently ask the customer to calmly head to the nearest Machine (that should hopefully
work fine).


In order to do so, a list of two-dimensional locations of all n ATMs has been prepared, and your task is to find for each of them the one closest with respect to the Euclidean distance.
 

 

Input
The input contains several test cases. The very first line contains the number of cases t (t <= 15) that follow. Each test cases begin with the number of Cash Machines n (2 <= n <= 10^5). Each of the next n lines contain the coordinates of one Cash Machine x,y (0 <= x,y <=10^9) separated by a space. No two
points in one test case will coincide.
 

 

Output
For each test case output n lines. i-th of them should contain the squared distance between the i-th ATM from the input and its nearest neighbour.
 

 

Sample Input
2
10
17 41
0 34
24 19
8 28
14 12
45 5
27 31
41 11
42 45
36 27
15
0 0
1 2
2 3
3 2
4 0
8 4
7 4
6 3
6 1
8 0
11 0
12 2
13 1
14 2
15 0
 
Sample Output
200
100
149
100
149
52
97
52
360
97
5
2
2
2
5
1
1
2
4
5
5
2
2
2
5
 

 

Source

 

注意,最近点不能是自己,所以需要判cur.first!=0时才加入队列中

 1 #include<iostream>
 2 #include<queue>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cstdio>
 6 #define N 100005
 7 using namespace std;
 8 
 9 int n,m,id;//n是点数,m是维度,id是当前切的维度
10 
11 struct sair{
12     long long p[5];
13     bool operator<(const sair &b)const{
14         return p[id]<b.p[id];
15     }
16 }_data[N],data[N<<3],tt[N];
17 int flag[N<<3];
18 
19 priority_queue<pair<long long,sair> >Q;
20 
21 void build(int l,int r,int rt,int dep){
22     if(l>r) return;
23     flag[rt]=1;
24     flag[rt<<1]=flag[rt<<1|1]=-1;
25     id=dep%m;
26     int mid=l+r>>1;
27     nth_element(_data+l,_data+mid,_data+r+1);
28     data[rt]=_data[mid];
29     build(l,mid-1,rt<<1,dep+1);
30     build(mid+1,r,rt<<1|1,dep+1);
31 }
32 
33 void query(sair p,int k,int rt,int dep){
34     if(flag[rt]==-1) return;
35     pair<long long,sair> cur(0,data[rt]);//获得当前节点
36     for(int i=0;i<m;i++){//计算当前节点到P点的距离
37         cur.first+=(cur.second.p[i]-p.p[i])*(cur.second.p[i]-p.p[i]);
38     }
39     int idx=dep%m;
40     int fg=0;
41     int x=rt<<1;
42     int y=rt<<1|1;
43     if(p.p[idx]>=data[rt].p[idx]) swap(x,y);
44     if(~flag[x]) query(p,k,x,dep+1);
45     //开始回溯
46     if(Q.size()<k){
47         if(cur.first!=0){
48             Q.push(cur);
49         }
50         fg=1;
51     }
52     else{
53         if(cur.first<Q.top().first){
54             if(cur.first!=0){
55                 Q.pop();
56                 Q.push(cur);
57             }
58         }
59         if((p.p[idx]-data[rt].p[idx])*(p.p[idx]-data[rt].p[idx])<Q.top().first){
60             fg=1;
61         }
62     }
63     if(~flag[y]&&fg){
64         query(p,k,y,dep+1);
65     }
66 }
67 
68 long long ans;
69 
70 
71 int main(){
72     int T;
73     scanf("%d",&T);
74     while(T--){
75         m=2;
76         scanf("%d",&n);
77         for(int i=1;i<=n;i++){
78             for(int j=0;j<m;j++){
79                 scanf("%lld",&_data[i].p[j]);
80                 tt[i].p[j]=_data[i].p[j];
81             }
82         }
83         build(1,n,1,0);
84         int k=1;
85         for(int i=1;i<=n;i++){
86             sair tmp;
87             for(int j=0;j<m;j++)
88                 tmp.p[j]=tt[i].p[j];
89             while(!Q.empty()){
90                 Q.pop();
91             }
92             query(tmp,k,1,0);
93             ans=Q.top().first;
94             Q.pop();
95             printf("%lld\n",ans);
96         }
97     }
98 }
View Code

 

转载于:https://www.cnblogs.com/Fighting-sh/p/9873378.html

#include “capi_google_hw_i.h” 3 4 #ifdef GOOGLE_ENABLE_LOG 5 #define GOOGLE_AR_MSG(…) AR_MSG(VA_ARGS) 6 #define GOOGLE_DE_DBG(…) DE_DBG(VA_ARGS) 7 #else 8 #define GOOGLE_AR_MSG(…) 9 #define GOOGLE_DE_DBG(…) 10 #endif 11 12 static int8_t gConfidence = 13 99; // Fixed confidence level for detection_engione_status_t payload 14 15 /---------------------------------------------------------------------------- 16 * Static function declarations 17 * -------------------------------------------------------------------------/ 18 static capi_err_t capi_google_hw_process(capi_t *_pif, 19 capi_stream_data_t *input[], 20 capi_stream_data_t *output[]); 21 static capi_err_t capi_google_hw_end(capi_t *_pif); 22 static capi_err_t capi_google_hw_set_param( 23 capi_t *_pif, uint32_t param_id, const capi_port_info_t *port_info_ptr, 24 capi_buf_t *params_ptr); 25 static capi_err_t capi_google_hw_get_param( 26 capi_t *_pif, uint32_t param_id, const capi_port_info_t *port_info_ptr, 27 capi_buf_t *params_ptr); 28 static capi_err_t capi_google_hw_set_properties(capi_t *_pif, 29 capi_proplist_t *props_ptr); 30 static capi_err_t capi_google_hw_get_properties(capi_t *_pif, 31 capi_proplist_t *props_ptr); 32 33 static capi_vtbl_t capi_google_hw_vtbl = { 34 capi_google_hw_process, capi_google_hw_end, 35 capi_google_hw_set_param, capi_google_hw_get_param, 36 capi_google_hw_set_properties, capi_google_hw_get_properties}; 37 38 #define CRC32_POLYNOMIAL 0xEDB88320 39 #define CRC32_SEED 0x0 capi_err_t capi_google_hw_init_util(capi_t *_pif, 125 capi_proplist_t *init_set_properties, 126 bool_t is_second_stage) { 127 capi_err_t result = CAPI_EOK; 128 129 if (NULL == _pif || (NULL == init_set_properties)) { 130 GOOGLE_AR_MSG(DBG_ERROR_PRIO, “capi_google_hw: Error! null pointer.”); 131 return CAPI_EBADPARAM; 132 } 133 134 capi_google_hw_t *me_ptr = (capi_google_hw_t *)_pif; 135 memset(me_ptr, 0, sizeof(capi_google_hw_t)); 136 137 GOOGLE_AR_MSG(DBG_HIGH_PRIO, 138 “capi_google_hw_init_util CAPI Ptr %p second_stage %d”, me_ptr, 139 is_second_stage); 140 me_ptr->sound_model_alignment = kGoogleHotwordRequiredDataAlignment; 141 me_ptr->sample_rate = SAMPLING_RATE; 142 me_ptr->sample_bits = BITS_PER_SAMPLE; 143 me_ptr->sound_model_info.sound_model_ptr = NULL; 144 me_ptr->sound_model_info.arena_ptr = NULL; 145 146 // identify stage 2 detection module 147 me_ptr->is_second_stage = is_second_stage; 148 149 // apply init time set properties 150 result = capi_google_hw_handle_set_properties(me_ptr, init_set_properties); 151 if (result == CAPI_EUNSUPPORTED) { 152 // unsupported error must be ignored for init set properties 153 result = CAPI_EOK; 154 } else if (CAPI_FAILED(result)) // for any other failures return error. 155 { 156 // Free the allocated capi memory 157 GOOGLE_AR_MSG(DBG_HIGH_PRIO, 158 “capi_google_hw_end in case of failure set+prop”); 159 capi_google_hw_end(_pif); 160 GOOGLE_DE_DBG(me_ptr->miid, DBG_ERROR_PRIO, “Init Failed!”); 161 } 162 163 // Initialize the capi handle. 164 me_ptr->vtbl_ptr = &capi_google_hw_vtbl; 165 me_ptr->is_enabled = TRUE; 166 167 GOOGLE_DE_DBG(me_ptr->miid, DBG_HIGH_PRIO, “Init done with result %d”, 168 result); 169 170 return result; 171 } 如何打开这段代码中的log打印
08-08
<think>我们注意到代码中使用了宏定义来控制日志打印。具体来说,在代码的第4行到第10行,有一个条件编译的宏定义: ```c #ifdef GOOGLE_ENABLE_LOG #define GOOGLE_AR_MSG(...) AR_MSG(__VA_ARGS__) #define GOOGLE_DE_DBG(...) DE_DBG(__VA_ARGS__) #else #define GOOGLE_AR_MSG(...) #define GOOGLE_DE_DBG(...) #endif ``` 这段代码的意思是:如果定义了宏`GOOGLE_ENABLE_LOG`,那么`GOOGLE_AR_MSG`和`GOOGLE_DE_DBG`就会被替换成对应的日志函数`AR_MSG`和`DE_DBG`;否则,这两个宏会被替换成空,即不执行任何操作。 因此,要打开这段代码中的日志打印,我们需要在编译时定义宏`GOOGLE_ENABLE_LOG`。 ### 如何定义宏 在C语言中,定义宏通常有以下几种方式: 1. 在代码中直接定义:在包含头文件之前,添加`#define GOOGLE_ENABLE_LOG`。 2. 在编译器命令行参数中定义:例如,使用gcc编译时,可以添加`-DGOOGLE_ENABLE_LOG`选项。 3. 在IDE的项目配置中定义宏(不同IDE方法不同)。 ### 具体步骤 假设我们使用gcc编译,那么可以在编译命令中加入`-DGOOGLE_ENABLE_LOG`,例如: ```bash gcc -DGOOGLE_ENABLE_LOG ... (其他编译选项) ... your_source_file.c ``` 这样,在编译时就会定义`GOOGLE_ENABLE_LOG`宏,从而启用日志打印。 ### 注意事项 1. 确保`AR_MSG`和`DE_DBG`函数已经定义和实现,否则编译时会报错。这些函数可能是项目中的其他日志函数,或者是外部库提供的。 2. 日志打印可能会影响性能,所以在生产环境中通常不启用。 ### 示例:在代码中定义(不推荐,因为需要修改源码) 如果不想修改编译命令,也可以在代码中定义这个宏。但是要注意,在包含头文件`capi_google_hw_i.h`之前定义,因为该头文件中的代码会使用这个宏。 例如,在文件开头添加: ```c #define GOOGLE_ENABLE_LOG #include "capi_google_hw_i.h" ``` 但是这种方法需要修改源码,通常不推荐,因为可能会被其他人修改回去,或者在不同配置下需要不同的定义。 ### 结论 推荐在编译时通过命令行参数定义宏`GOOGLE_ENABLE_LOG`来打开日志打印。 ### 相关问题 根据要求,在最后提出相关问题。 §§相关问题§§: 1. 在C语言中,条件编译还有哪些常见的用途? 2. 除了使用宏定义控制日志,还有哪些常见的日志控制方法? 3. 在大型项目中,如何管理不同模块的日志级别? 4. 如何实现日志的分级输出(如DEBUG、INFO、ERROR等级别)?</think>要打开这段代码中的日志打印功能,需要定义宏 `GOOGLE_ENABLE_LOG`。以下是详细解决方案: ### 解决方案 代码通过条件编译控制日志打印: ```c #ifdef GOOGLE_ENABLE_LOG #define GOOGLE_AR_MSG(...) AR_MSG(__VA_ARGS__) #define GOOGLE_DE_DBG(...) DE_DBG(__VA_ARGS__) #else #define GOOGLE_AR_MSG(...) #define GOOGLE_DE_DBG(...) #endif ``` 当未定义 `GOOGLE_ENABLE_LOG` 时,日志宏会被替换为空操作。要启用日志,需在编译时定义该宏。 #### 方法1:修改编译命令(推荐) 在编译命令中添加 `-DGOOGLE_ENABLE_LOG` 参数: ```bash gcc -DGOOGLE_ENABLE_LOG your_source_file.c -o output ``` #### 方法2:在代码中定义宏 在包含头文件前添加宏定义: ```c #define GOOGLE_ENABLE_LOG // 添加此行 #include "capi_google_hw_i.h" ``` #### 方法3:配置项目构建系统 在构建系统(如CMake)中添加定义: ```cmake add_definitions(-DGOOGLE_ENABLE_LOG) ``` ### 代码说明 1. **日志宏的作用**: - `GOOGLE_AR_MSG`:用于通用日志(如第130行的错误日志) - `GOOGLE_DE_DBG`:用于调试引擎日志(如第160行) 2. **关键日志点示例**: ```c // 错误日志(第130行) GOOGLE_AR_MSG(DBG_ERROR_PRIO, "capi_google_hw: Error! null pointer."); // 调试日志(第167行) GOOGLE_DE_DBG(me_ptr->miid, DBG_HIGH_PRIO, "Init done with result %d", result); ``` 3. **日志级别常量**: - `DBG_ERROR_PRIO`:错误级别 - `DBG_HIGH_PRIO`:高优先级信息 - 这些常量由底层日志系统实现 ### 验证方法 编译运行后,以下日志将被输出: 1. 初始化信息(第137行) 2. 错误信息(如空指针错误) 3. 初始化结果(第167行)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值