【HDU】4995 Revenge of kNN 暴力

传送门:【HDU】4995 Revenge of kNN


题目分析:保存离每个点K近的数的下标,然后暴力更新即可。


代码如下:


#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std ;

#define REP( i , a , b ) for ( int i = a ; i < b ; ++ i )
#define REV( i , a , b ) for ( int i = a ; i >= b ; -- i )
#define FOR( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define CLR( a , x ) memset ( a , x , sizeof a )
#define CPY( a , x ) memcpy ( a , x , sizeof a )
#define s1 o * 4 + 1
#define s2 o * 4 + 2
#define s3 o * 4 + 3
#define s4 o * 4 + 4
#define Lower_Left s1 , lx , mx , ly , my
#define Upper_Left s2 , lx , mx , my + 1 , ry
#define Lower_Right s3 , mx + 1 , rx , ly , my
#define Upper_Right s4 , mx + 1 , rx , my + 1 , ry
#define midx ( ( lx + rx ) >> 1 )
#define midy ( ( ly + ry ) >> 1 )
#define root 0 , 1 , n , 1 , 1000

const int MAXN = 100005 ;
const int MAXE = 1000005 ;

struct Node {
	int x , idx ;
	double v ;
	Node () {}
	Node ( int x , int idx ) : x ( x ) , idx ( idx ) {}
} p[MAXN] , S[MAXN] ;

struct Edge {
	int v , n ;
	Edge () {}
	Edge ( int v , int n ) : v ( v ) , n ( n ) {}
} E[MAXE] ;

int H[MAXN] , cntE ;
int top ;
int n , m , k ;

void clear () {
	cntE = 0 ;
	CLR ( H , -1 ) ;
}

void addedge ( int u , int v ) {
	E[cntE] = Edge ( v , H[u] ) ;
	H[u] = cntE ++ ;
}

int cmp1 ( const Node& a , const Node& b ) {
	if ( a.x != b.x ) return a.x < b.x ;
	return a.idx < b.idx ;
}

int cmp2 ( const Node& a , const Node& b ) {
	return a.idx < b.idx ;
}

void solve () {
	int u ;
	double ans = 0 ;
	clear () ;
	scanf ( "%d%d%d" , &n , &m , &k ) ;
	k = min ( n - 1 , k ) ;
	FOR ( i , 1 , n ) {
		scanf ( "%d%lf" , &p[i].x , &p[i].v ) ;
		p[i].idx = i ;
	}
	sort ( p + 1 , p + n + 1 , cmp1 ) ;
	FOR ( i , 1 , n ) {
		int L = i - 1 , R = i + 1 ;
		top = 0 ;
		REP ( j , 0 , k ) {
			if ( L && R <= n ) {
				if ( p[i].x - p[L].x == p[R].x - p[i].x ) {
					if ( p[L].idx < p[R].idx ) addedge ( p[i].idx , p[L --].idx ) ;
					else addedge ( p[i].idx , p[R ++].idx ) ;
				}
				else if ( p[i].x - p[L].x < p[R].x - p[i].x ) addedge ( p[i].idx , p[L --].idx ) ;
				else addedge ( p[i].idx , p[R ++].idx ) ;
			}
			else if ( L ) addedge ( p[i].idx , p[L --].idx ) ;
			else addedge ( p[i].idx , p[R ++].idx ) ;
		}
	}
	sort ( p + 1 , p + n + 1 , cmp2 ) ;
	while ( m -- ) {
		scanf ( "%d" , &u ) ;
		double val = 0 ;
		for ( int i = H[u] ; ~i ; i = E[i].n ) val += p[E[i].v].v ;
		p[u].v = val / k ;
		ans += val / k ;
	}
	printf ( "%.6f\n" , ans ) ;
}

int main () {
	int T ;
	scanf ( "%d" , &T ) ;
	while ( T -- ) solve () ;
	return 0 ;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值