#温馨提示:此文章使用的是MD编辑器,在小程序上查看可能会出现乱码,敬请谅解
题目介绍
题目描述
本题难度:普及-
算法标签:模拟 枚举
为了准备一个独特的颁奖典礼,组织者在会场的一片矩形区域(可看做是平面直角坐标系的第一象限)铺上一些矩形地毯。一共有 n n n 张地毯,编号从 1 1 1 到 n n n。现在将这些地毯按照编号从小到大的顺序平行于坐标轴先后铺设,后铺的地毯覆盖在前面已经铺好的地毯之上。
地毯铺设完成后,组织者想知道覆盖地面某个点的最上面的那张地毯的编号。注意:在矩形地毯边界和四个顶点上的点也算被地毯覆盖。
输入格式
输入共 n + 2 n + 2 n+2 行。
第一行,一个整数 n n n,表示总共有 n n n 张地毯。
接下来的 n n n 行中,第 i + 1 i+1 i+1 行表示编号 i i i 的地毯的信息,包含四个整数 a , b , g , k a ,b ,g ,k a,b,g,k,每两个整数之间用一个空格隔开,分别表示铺设地毯的左下角的坐标 ( a , b ) (a, b) (a,b) 以及地毯在 x x x 轴和 y y y 轴方向的长度。
第 n + 2 n + 2 n+2 行包含两个整数 x x x 和 y y y,表示所求的地面的点的坐标 ( x , y ) (x, y) (x,y)。
输出格式
输出共
1
1
1 行,一个整数,表示所求的地毯的编号;若此处没有被地毯覆盖则输出 -1
。
样例 #1
样例输入 #1
3
1 0 2 3
0 2 3 3
2 1 3 3
2 2
样例输出 #1
3
样例 #2
样例输入 #2
3
1 0 2 3
0 2 3 3
2 1 3 3
4 5
样例输出 #2
-1
提示
【样例解释 1】
如下图, 1 1 1 号地毯用实线表示, 2 2 2 号地毯用虚线表示, 3 3 3 号用双实线表示,覆盖点 ( 2 , 2 ) (2,2) (2,2) 的最上面一张地毯是 3 3 3 号地毯。
【数据范围】
对于
30
%
30\%
30% 的数据,有
n
≤
2
n \le 2
n≤2。
对于
50
%
50\%
50% 的数据,
0
≤
a
,
b
,
g
,
k
≤
100
0 \le a, b, g, k \le 100
0≤a,b,g,k≤100。
对于
100
%
100\%
100% 的数据,有
0
≤
n
≤
1
0
4
0 \le n \le 10^4
0≤n≤104,
0
≤
a
,
b
,
g
,
k
≤
10
5
0 \le a, b, g, k \le {10}^5
0≤a,b,g,k≤105。
时间限制:
1.00
s
1.00s
1.00s,空间限制:
125.00
M
B
125.00MB
125.00MB。
Noip2011 提高组 day1 第 1 1 1 题。
题解代码及思路
第一次尝试(MLE)
开一个二维数组,记录每个格子的状态,但是…
数据范围是
0
≤
n
≤
1
0
4
0 \le n \le 10^4
0≤n≤104
于是成功MLE(超空间)了
MLE代码如下
// C++
#include<iostream>
#include<cstring>
using namespace std;
int f[10001][10001];
int main(){
memset(f,-1,sizeof(f));
int n;
cin>>n;
for(int i=1;i<=n;i++){
int a,b,g,k;
cin>>a>>b>>g>>k;
for(int x=a;x<=a+g;x++){
for(int y=b;y<=b+k;y++){
f[x][y]=i;
}
}
}
int x,y;
cin>>x>>y;
cout<<f[x][y]<<endl;
return 0;
}
第二次尝试(AC)
那么,怎么办呢?
我们可以尝试用两个数组记录每张地毯的左下角和右上角,再从后向前看看输入的点在不在某个地毯里,如果是就输出并结束程序。
AC代码如下
// C++
#include<iostream>
using namespace std;
int a[10001][2], b[10001][2];// 定义二维数组a和b用于存储地毯的左下角坐标以及右上角坐标
int main()
{
int n,g,k;
cin>>n;//读取地毯总数
for (int j=1;j<=n;j++){
cin>>a[j][0]>>a[j][1]>>g>>k;
b[j][0]=a[j][0]+g;//计算地毯的右上角坐标
b[j][1]=a[j][1]+k;
}
int x,y;
cin>>x>>y;// 读取所求点的坐标
for (int j=n;j>=1;j--){// 从后往前遍历地毯编号,检查所求点是否在地毯范围内
if (x >= a[j][0] && x <= b[j][0] && y >= a[j][1] && y <= b[j][1]){ // 若该点被地毯j覆盖
cout<<j; // 输出地毯编号
return 0; // 结束程序
}
}
cout<<-1;// 若没有地毯覆盖该点,则输出-1
return 0;
}