[巴解组织] 地震的问题 – OLP信息 2012 超级块

帖子 3: 地震
限制每次测试的时间: 1 秒.
在河柠檬ñ户居住的银行. 这是一个住宅区往往遭受地震强度不同. 关于地震的信息Q包括三个整数 (X, 和, ˚F), 哪:

– (X, 和) 是Q地震的震中;
– f是在震中测得的地震Q的大小 (X,和).

一个家庭位于该位置 (X', 和') 据推测受地震影响Q = (X, 和, ˚F) 如果: sqrt{(x-x')^{2}+(y-y')^{2}} leqslant f^2

过去一个月内, 地震监测中心检测到在清河地区发生的所有P地震. 如果一个家庭至少受到上述P次地震中的K次地震的影响,则据说该家庭受到地震的严重影响。. 评估地震对昌河两岸居民区的影响, 地方当局需要计算受地震严重影响的家庭数量.

要求: 提供有关地震和家庭所在地的信息, 计算受地震严重影响的家庭数量.
数据: 从文本文件EQ.INP输入,包括N + P + 1行:

– 第一行包含 3 正整数N, P, ķ (N≤ 500000, P≤ 5000);
– 接下来的N行包含N个住户的坐标. N行中的第i行包含 2 整数xi , yi是第i户的坐标 (0 ≤ xi ≤ 10 6 , 0 ≤ yi ≤ 100).
– 接下来的P行包含有关P地震的信息. P行的第i行包含 3 整数xi , yi , fi是地震信息.

结果: 给EQ.OUT文本文件一个整数,该整数是受地震严重影响的家庭数量.

地震 - 奥运超级杯 2012
==========

实际上,我也已经搜索了问题的解决方案,但是没有找到任何写的页面. 我的一些兄弟遵循以下算法, 当然还不是最佳的, 我们希望您能更好地完成本课.

首先,我们将回顾任何人看到的最简单的方法是考虑每所房子, 每一座房子我们都会像地震一样闪电, 如果受到影响,请增加计数 (转夜地震号) 向上 1 或考虑每次地震, 每场比赛,考虑N座房屋. 最后,我们只需要计算有多少间房屋受到k场或更多场比赛的影响. 就是这样,蜜蜂@@
但是您可以使用N查看我们的数据 <= 500.000 和P <= 5.000 太大,无法执行每个测试 1 秒. 我们将学习更好的方法 (不确定这是否是最好的方法). =))

首先,我们看到需要解决的问题,我们将寻找受地震影响的点, 接下来的事情是计算并比较哪些得分超过k个游戏. 我们注意到的重要一点是<=100. 所以我们将注意力转向它.
我们注意到,每次地震的影响程度为 1 中心圆 (X, 和) 半径是f ^ 2. 每行y = a (0 <= A <= 100) 那么每一次地震 1 大约 (1 直段) 我们需要确定那条线, 下一步是确定其中的住户并增加其数量. 从这里我们将问题带回来 2 儿童问题:
1. 确定穿过地震产生的圆和线y = a的线段 (数据准备).
2. 对于问题中确定的每条直线 1 我们将识别该行中的家庭 (数据处理).

* 对于第一个问题,我们可以简单地定义与中心圆相交的线段 (X, 和) 半径f ^ 2和线y = a等于公式: x_{p} - sqrt{f^{4}-(y-a)^{2}} leqslant x leqslant x_{p} + sqrt{f^{4}-(y-a)^{2}}
* 数学问题 2, 能够识别该行中的家庭, 我们沿着x坐标的升序排列住户并进行搜索 (可以使用二进制搜索 ) 2 地标是 2 隔膜 2 第一个和最后一个家庭在该范围内. (X1 <= X <= X2).
地震 - 电脑奥林匹克超级杯 2012

这里是代码:

#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;

struct point {		// diem trong he toa do
    int x, y;
};

bool operator * ( const point &t, const point &u ){	// dinh nghia phep toan "*"
	return t.x > u.x;								//sap xep tang dan theo x
}

int my_compare (const void * a, const void * b){
	return ( *( point*)a * *(point*)b );			//chi duoc su dung phep toan "*" de sap xep
}

int main(){
    int n, p, k, ans = 0;
    cin >> n >> p >> k;

    point A[n], B[p];	//A[i] toa do cac ho gia dinh, B[i] toa do tam tran dong dat
    float f[p];			// cuong do tran dong dat thu i
    int c[n], A1[n];	// c[i] so tran dong dat ma ho gia dinh i phai chiu, 
						// A1[i] hoanh do cac ho gia dinh da sap xep

    for (int i = 0; i < n; i++) {				// nhap du lieu	
        cin >> A[i].x >> A[i].y;
        c[i] = 0;
    }
    
    for (int i = 0; i < p; i++) {				
        cin >> B[i].x >> B[i].y >> f[i];
    }

    qsort (A, n, sizeof(point), my_compare);	// sap xep cac ho gia dinh theo hoanh do
	for (int i = 0; i < n; i++)					// copy hoanh do cac ho gia dinh ra A1
		A1[i] = A[i].x;

    for (int i = 0; i <= 100; i++) {
        for (int j = 0 ; j < p; j++) {
			float temp = f[j]*f[j]*f[j]*f[j] - (B[j].y - i)*(B[j].y - i);
			if (temp >= 0){
				float x1 = B[j].x - sqrt(temp);
				float x2 = B[j].x + sqrt(temp);

				int temp1, temp2;
				
				temp1 = lower_bound(A1, A1 + n, x1) - A1;	// vi tri ho gia dinh dau tien trong doan x1, x2
				temp2 = upper_bound(A1, A1 + n, x2) - A1;
				temp2--;									// vi tri ho gia dinh cuoi cung trong doan x1, x2
				
				if (temp1 < n && temp2 < n) {				// tang so tran dong dat tai moi nha trong doan x1, x2
					for (int l = temp1; l <= temp2; l++)
						if (i == A[l].y) {
							c[l]++;
						}		
				}
			} 
        }
    }
    for (int i=0; i<n; i++)
		if (c[i] >= k) ans++ ;
	cout << ans << endl;
    return 0;
}

在上面的代码中,我使用了一些技术和功能:
– 通过排列数组结构 1 通过快速排序结构部件. 更多信息请访问 快速排序 - 相关问题
– 火腿LOWER_BOUND(A1, A1 + ñ, X1) 返回指针的第一个元素 >= A1中的x1. Hàmupper_bound(A1, A1 + ñ, X2) 返回指针的第一个元素 > A1中的x2. 所以我们需要减去A1来获得位置, 并随着temp2需要降低 1 单位x <= x2是段落x1中的最后一个元素, x2我们需要找到.

查看更多考试: 奥尔普