• BestCoder9 1003 Revenge of kNN(hdu 4995) 解题报告


    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4995

    题目意思:在一个一维坐标轴上,给出位置 xi 和值 vi,对于 M 次询问,每次询问给出index Qi,求出离数组下标 Qi(从1开始) 最近的 K 个点,从新计算该下标所指示的value值,即等于 K 个 最近点的value值之和 / K,如果有多个K的最近点,那么选择坐标值靠前的那组。

        模拟题。首先对将位置(因为输入不一定按顺序从左至右递增排序,样例有骗人的嫌疑)从小到大排序,然后求出每一个点的 K 个最近点,最近是通过xi 离当前 xpos 的距离来判断的,不断试探。如果发现左边的点的xl 比 右边的的点 xr 离 xi的距离近,那么就选左边的点,所以要通过进一步排序比较,Judge()函数中return point[pos].xi - point[l].xi < point[r].xi - point[pos].xi; 就是通过比较两边距离值来决定是选左边的那个点还是右边的那个点。(处理得非常地巧妙) 

        这个代码是学人家的,自以为看懂,写起来还是反反复复修改了很多次才成功~~~

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstdlib>
     4 #include <cstring>
     5 #include <algorithm>
     6 #include <vector>
     7 using namespace std;
     8 
     9 typedef __int64 LL;
    10 const int maxn = 1e5 + 5;
    11 double vi[maxn];
    12 vector<int> g[maxn];
    13 int N, M, K;
    14 
    15 struct node
    16 {
    17     int id, xi;
    18 }point[maxn];
    19 
    20 int cmp(const node& a, const node& b)
    21 {
    22     return a.xi < b.xi;
    23 }
    24 
    25 bool Judge(int pos, int l, int r)
    26 {
    27     if (r > N)
    28         return true;
    29     if (l <= 0)
    30         return false;
    31     if (point[pos].xi - point[l].xi != point[r].xi - point[pos].xi)  // 离两边距离值不同,选择距离值更小的那个点
    32         return point[pos].xi - point[l].xi < point[r].xi - point[pos].xi;
    33     return point[l].id < point[r].id;  // 如果离两边的距离值相同,那么选择坐标值小的那个
    34 }
    35 
    36 void Get_KNN(int pos)   // 获得每个点的最近 k 个点是那些
    37 {
    38     int id = point[pos].id;
    39     int l = pos - 1, r = pos + 1;
    40     for (int i = 0; i < K; i++)   
    41     {
    42         if (Judge(pos, l, r))
    43             g[id].push_back(point[l--].id);
    44         else
    45             g[id].push_back(point[r++].id);
    46     }
    47 }
    48 
    49 int main()
    50 {
    51     int T;
    52     while (scanf("%d", &T) != EOF)
    53     {
    54         while (T--)
    55         {
    56             scanf("%d%d%d", &N, &M, &K);
    57             for (int i = 1; i <= N; i++)
    58             {
    59                 scanf("%d%lf", &point[i].xi, &vi[i]);
    60                 point[i].id = i;
    61             }
    62             sort(point+1, point+1+N, cmp);
    63             for (int i = 1; i <= N; i++)
    64                 Get_KNN(i);
    65             int ask;
    66             double ans = 0;
    67             for (int i = 0; i < M; i++)
    68             {
    69                 scanf("%d", &ask);
    70                 double sum = 0;
    71                 for (int j = 0; j < g[ask].size(); j++)
    72                     sum += vi[g[ask][j]];
    73                 vi[ask] = sum / K;
    74                 ans += vi[ask];
    75             }
    76             printf("%.6lf
    ", ans);
    77             for (int j = 1; j <= N; j++)
    78                 g[j].clear();
    79         }
    80     }
    81     return 0;
    82 }
    View Code
  • 相关阅读:
    通过JavaMail发送(群发)邮件示例(内含附件图片) 代码复制可用
    需要把获取系统的当前时间存入库里 获取时是String类型,库里是Datetime类型 String 转化 Date
    用canvas和原生js写的一个笨鸟先飞的小游戏(暂时只有一个关卡)
    Svg和canvas的区别,伪类选择器有哪些(归类)
    微信web网页动态增减输入框,搜索框,基于jQuery weui、jQuery 实现无限插入数据,动态数据生成,外加高德地图POI和根据坐标获取位置信息的页面
    vue 使用tinymce富文本编辑器
    mamp环境下navicat无法链接本地mysql
    tp5 系统变量输出
    开始项目注意事项
    jQuery weui实现下拉刷新事件
  • 原文地址:https://www.cnblogs.com/windysai/p/3989556.html
Copyright © 2020-2023  润新知