HDU - 4995 - Revenge of kNN

题目链接 : https://vjudge.net/problem/HDU-4995

题目大意  :   读入n个点的坐标与该点所拥有的值val,进行m次查询,对于每一次查询,读入该点的坐标,计算离该点最近的k个点的值(距离相同的索引小的优先),进行求和求平均,

然后更新改点的值,最后输出更新的值的和。

题目分析  :   一个比较不错的模拟的题目,可以对坐标值和 索引进行hash来优化计算时间。

其他进行模拟即可,注意读入的值并不是有序的,需要先进行排序。

代码实现 :

  1 #include <iostream>
  2 #include <cstring>
  3 #include <queue>
  4 #include <algorithm>
  5 #include <cstdio>
  6 using namespace std;
  7 int m,n,k;
  8 struct node
  9 {
 10     double point;
 11     double val;
 12     int id;
 13 };
 14 bool comp(const node &a,const node& b)
 15 {
 16     return a.point<b.point;
 17 }
 18 int hashs[110000+10];
 19 node nodes[110000+10];
 20 void init()
 21 {
 22     cin>>n>>m>>k;
 23     for(int i=0;i<n;i++)
 24     {
 25         double a;
 26         double b;
 27         scanf("%lf%lf",&a,&b);
 28         nodes[i].point=a;
 29         nodes[i].val=b;
 30         nodes[i].id = i;
 31     }
 32     sort(nodes,nodes+n,comp);
 33     for(int i=0;i<n;i++)
 34     {
 35         hashs[nodes[i].id+1]=i;
 36     }
 37 }
 38 double solve()
 39 {
 40     double SUM=0;
 41     for(int i=0;i<m;i++)
 42     {
 43         int t;
 44         scanf("%d",&t);
 45      //   cout<<t<<endl;
 46         int mid=hashs[t];
 47         int l=mid-1,r=mid+1;
 48         int K=k;
 49         double sum=0;
 50         while(K--)
 51         {
 52             if(l>=0&&r<n)
 53             {
 54                 double d1=nodes[l].point;
 55                 double d2=nodes[r].point;
 56                 double t1=nodes[mid].point-d1;
 57                 double t2=d2-nodes[mid].point;
 58                // cout<<t1<<" "<<t2<<" "<<"*"<<endl;
 59                 if(t1<t2)
 60                 {
 61                     sum+=nodes[l].val;
 62                    // cout<<nodes[l].val<<" "<<l<<endl;
 63                     l--;
 64                 }
 65                 else if(t1>t2)
 66                 {
 67                     sum+=nodes[r].val;
 68                //     cout<<nodes[r].val<<" "<<r<<endl;
 69                     r++;
 70                 }else if(t1==t2)
 71                 {
 72                     if(nodes[l].id<nodes[r].id)
 73                     {
 74                         sum+=nodes[l].val;
 75                         l--;
 76                     }
 77                     else
 78                     {
 79                         sum+=nodes[r].val;
 80                         r++;
 81                     }
 82                 }
 83             }
 84             else if(l>=0)
 85             {
 86                 sum+=nodes[l].val;
 87               //  cout<<nodes[l].val<<" "<<l<<endl;
 88                 l--;
 89             }else if(r<n)
 90             {
 91                 sum+=nodes[r].val;
 92              //   cout<<nodes[r].val<<" "<<r<<endl;
 93                 r++;
 94             }
 95         }
 96       //  cout<<sum<<" *"<<endl;
 97         sum=sum/k;
 98         //cout<<sum<<endl;
 99         SUM+=sum;
100         nodes[mid].val=sum;
101     }
102     return SUM;
103 }
104 int main()
105 {
106     int T;
107     cin>>T;
108     while(T--)
109     {
110        init();
111        double sum=solve();
112        printf("%.6lf\n",sum);
113     }
114     return 0;
115 }

时间: 2024-10-11 15:55:00

HDU - 4995 - Revenge of kNN的相关文章

hdu 4995(离散化下标+模拟)

Revenge of kNN Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 584    Accepted Submission(s): 136 Problem Description In pattern recognition, the k-Nearest Neighbors algorithm (or k-NN for short

HDU 4994 Revenge of Nim (博弈)

题目链接:HDU 4994 Revenge of Nim 题意:两个取石头,分别在N堆里去.只有第一堆取完才能取第二堆,以此类推,最后一个取完的为赢家. 思路:从头开始扫,直到第一个不为1为止,判断现在的主动权在谁手里,谁就是赢家.(这里读者可以自己写几组数据试试.) AC代码: #include<stdio.h> #include<string.h> int main() { int yaoga; int t,i,n; int a[1010]; while(scanf("

hdu 5087 Revenge of LIS II(LIS)

题目连接:hdu 5087 Revenge of LIS II 题目大意:给定一个序列,求第2长的LIS长度. 解题思路:用o(n^2)的算法求LIS,每个位置维护两个值,最大和最小即可.注意的是dp[0]中的最大第二大不能都复制成0. #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 1005; int N, A[maxn],

hdu 5088 Revenge of Nim II(高斯消元)

题目链接:hdu 5088 Revenge of Nim II 题目大意:Nim游戏的变形,因为游戏很不公平,所以现在转变规则,后手可以选取若干堆石子剔除,剩下堆的石子用 来进行游戏,问说后手可能胜利吗. 解题思路:其实即为取出非0堆石子,使得Nim和为0.因为是Nim和(亦或),所以以每个位建立方程,列出40个方 程,进行亦或形式的高斯消元,因为全0肯定为一解,所以方程肯定有解,那么存在多解的情况即为存在自有变元. #include <cstdio> #include <cstring

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

HDU - 4994 Revenge of Nim

Problem Description Nim is a mathematical game of strategy in which two players take turns removing objects from distinct heaps. On each turn, a player must remove at least one object, and may remove any number of objects provided they all come from

HDU 5018 Revenge of Fibonacci(数学)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5018 Problem Description In mathematical terms, the sequence Fn of Fibonacci numbers is defined by the recurrence relation Fn = Fn-1 + Fn-2 with seed values F1 = 1; F2 = 1 (sequence A000045 in OEIS). ---

HDU 5019 Revenge of GCD(数学)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5019 Problem Description In mathematics, the greatest common divisor (gcd), also known as the greatest common factor (gcf), highest common factor (hcf), or greatest common measure (gcm), of two or more i

HDU 4993 Revenge of ex-Euclid(数学题 暴力)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4993 Problem Description In arithmetic and computer programming, the extended Euclidean algorithm is an extension to the Euclidean algorithm, which computes, besides the greatest common divisor of intege