本文最后更新于 35 天前,其中的信息可能已经有所发展或是发生改变。
文献参考
题目描述
为了准备一个独特的颁奖典礼,组织者在会场的一片矩形区域(可看做是平面直角坐标系的第一象限)铺上一些矩形地毯。一共有 nn 张地毯,编号从 11 到 nn。现在将这些地毯按照编号从小到大的顺序平行于坐标轴先后铺设,后铺的地毯覆盖在前面已经铺好的地毯之上。
地毯铺设完成后,组织者想知道覆盖地面某个点的最上面的那张地毯的编号。注意:在矩形地毯边界和四个顶点上的点也算被地毯覆盖。
代码演示
//小笨蛋版
#include<iostream>
#include<vector>
#include<unordered_map>
using namespace std;
int main()
{
unordered_map<long long, int> ground;
int n;
cin >> n;
for(int v = 1; v <= n; v++)
{
int a, b, g, k;
cin >> a >> b >> g >> k;
for(int i = a; i <= a + g; i++)
{
for(int j = b; j <= b + k; j++)
{
ground[(long long)i * 1000000 + j] = v;
}
}
}
int o, p;
cin >> o >> p;
if(ground[(long long)o * 100000 + p])
{
cout << ground[(long long)o * 100000 + p] << endl;
}else{
cout << "-1" << endl;
}
return 0;
}
在此之前已经抛弃了二维数组模拟地板的算法(4亿字节1600G),改用如上算法,即map(这里是unordered_map无序算法)字典法。因为二维数组大部分数据是无需用到的,那么就采用字典法,用10000隔开两个坐标比如20003代表(2,3)作为字典的键(搜索词)然后给收缩词赋值,当我们在用map搜索的时候并未搜索赋值则采用默认值。但…运行内存还是太大了!
//聪明宝宝版
#include<iostream>
using namespace std;
const int edgemax = 100000;
int a[edgemax], b[edgemax], g[edgemax], k[edgemax];
int main() {
int n, x, y;
cin >> n;
for(int i = 0; i < n; i++) {
cin >> a[i] >> b[i] >> g[i] >> k[i];
}
cin >> x >> y;
int ans = -1;
for(int i = 0; i < n; i++) {
if(x >= a[i] && y >= b[i] && x <= a[i] + g[i] && y <= b[i] + k[i]) {
ans = i + 1;
}
}
cout << ans << endl;
return 0;
}
关键的问题就是抓住问题的关键!这里用四个一维数组记录了表示矩形位置和大小的关键要素(左下角点坐标[A][B]和长[G][,宽[K])那么我们将检测点对比的时候就可以直到监测点的横纵表与纵坐标是否能满足在这个矩形里面。主要思路:1.创建四个一维数组用于储存起始点横坐标,起始点纵坐标,和矩形的长宽2.输入3.一个巧妙的ans=-14.从上至下遍历输入的数值并不断和监测点xy做对比,一旦在此则ans立刻编程i所对应的堆叠数i+1.与上面字典不同,字典储存的数据是平方倍,而四个一维数组则是4*1倍。