题解:CF1137A Skyscrapers
CF1137A 题目传送门
题目大意
给出一个
解决思路
概念理解
首先了解新概念离散化。
离散化,把无限空间中有限的个体映射到有限的空间中去,以此提高算法的时空效率。通俗的说,离散化是在不改变数据相对大小的条件下,对数据进行相应的缩小。
分别离散化每一行和每一列,然后使用二分得出每行和每列中分别有几个数比它大和比它小。在这一行一列中最多有
代码展示
#include <iostream>
using namespace std;
const int N = 1010;
int n, m, x[N][N], a[N][N];
int b[N][N], va[N], vb[N], xa, ya;
int main()
{
scanf("%d%d", &n, &m);//建议scanf,更快
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
{
scanf("%d", &x[i][j]);
a[i][j] = x[i][j];//行离散化
b[j][i] = x[i][j];//列离散化
}
for(int i = 1; i <= n; i++)
{//离散化第 1 ~ n 行
sort(a[i] + 1, a[i] + m + 1);//排序第i行
va[i] = unique(a[i] + 1, a[i] + m + 1) - a[i] - 1;//va存储去重后的数组长度
//unique函数可以对数组去重
}
for(int i = 1; i <= m; i++)
{//离散化第 1 ~ m 列
sort(b[i] + 1, b[i] + n + 1);//排序第i列
vb[i] = unique(b[i] + 1, b[i] + n + 1) - b[i] - 1;//va存储去重后的数组长度
}
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= m; j++)
{
xa = lower_bound(a[i], a[i] + va[i], x[i][j]) - a[i];//二分查找x[i][j]在第i行从小到大排第几
ya = lower_bound(b[j], b[j] + vb[j], x[i][j]) - b[j];//二分查找x[i][j]在第i列从小到大排第几
int xb = va[i] - xa, yb = vb[j] - ya;
printf("%d ", max(xa, ya) + max(xb, yb));//建议printf,更快
}
printf("\n");//换行是个好习惯
}
return 0;
}