二维坐标离散化

离散化,把无限空间中有限的个体映射到有限的空间中去,以此提高算法的时空效率。
通俗的说,离散化是在不改变数据相对大小的条件下,对数据进行相应的缩小。 —百度百科

经常遇到二维坐标分不大,但数据量少,即稀疏的二维坐标的题。
P3431 [POI2005]AUT-The Bus
一个二维坐标,x 轴的取值为[1, 1e9], y 轴的取值为[1, 1e9], 但数据只有 k(<=5000)
这1e9 * 1e9的图有用的点,最大为 5000,我们也建不了1e9 * 1e9的二维坐标,且程序运行时间大幅上升
这时候就需要对其进行离散化

就是对较大的坐标值,我们用较小的值来描述该点,也能够表示处理前各点之间的关系
用实例来描述该方法,对(5, 5000),(901, 300),(900, 6), 进行离散化

对 x 轴离散化:先对 x 轴的点去重排序得到 5,900,901:5 -> 1,因为 5 与 900 不相邻,则900 -> 3,900 与 901 相邻,则901 -> 4
5, 900, 901 --> 1, 3, 4。依旧保留了之前相邻的关系

对 y 轴离散化:先对 y 轴的点去重排序得到 6, 300, 5000:6 -> 1, 因为6 与 300 不相邻,则300 -> 3,300 与 5000不相邻,则 5000 -> 5
6, 300, 5000 --> 1, 3, 5
最后离散后得到的点为 (1,5),(4,3 ),(3,1)

代码实现:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e3;
int n, m, k, ans;
int x[maxn], y[maxn];
int nx[maxn*2], ny[maxn*2];
int tot1 = 1, tot2 = 1;
int mp[maxn*2][maxn*2];
struct node {
	int x, y;
}a[maxn];

int main(){
	cin >> n >> m >> k;
	for(int i = 0; i < k; i++){
		cin >> x[i] >> y[i];
		a[i].x = x[i], a[i].y = y[i];
	}
	
	// 排序 
	sort(x , x + k);
	sort(y, y + k);
	// 去重 并得到有多少个点 
	int len1 = unique(x , x + k) - x;
	int len2 = unique(y , y + k) - y;

	// 离散化 x 轴
	for(int i = 0; i < len1; i++){
		if(i && x[i] != x[i - 1] + 1)
			nx[tot1++] = x[i] - 1, nx[tot1++] = x[i];
		else
			nx[tot1++] = x[i];
	}
	for(int i = 0; i < tot1; i++)
		cout << nx[i] << " ";
	cout << endl;
	// 离散化 y 轴
	for(int i = 0; i < len2; i++){
		if(i && y[i] != y[i - 1] + 1)
			ny[tot2++] = y[i] - 1, ny[tot2++] = y[i];
		else
			ny[tot2++] = y[i];
	}
	// 
	for(int i = 0; i < k; i++){
		int newx = lower_bound(nx, nx + tot1, a[i].x) - nx;
		int newy = lower_bound(ny, ny + tot2, a[i].y) - ny;
		mp[newx][newy] = 1;
	}
	
	for(int i = 1; i < tot1; i++){
		for(int j = 1; j < tot2; j++)
			cout << mp[i][j] << " ";
		cout << endl;
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值