C/C++洛谷---P1003 [NOIP2011 提高组] 铺地毯

个人主页:

小白,请指教。_小项目,数据结构,选择题-CSDN博客

专题分栏:洛谷刷题

https://blog.csdn.net/qq_73435980/category_12427681.html

一、题目

详细题目链接:

P1003 [NOIP2011 提高组] 铺地毯 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

题目

为了准备一个独特的颁奖典礼,组织者在会场的一片矩形区域(可看做是平面直角坐标系的第一象限)铺上一些矩形地毯。一共有 n 张地毯,编号从 1 到 n。现在将这些地毯按照编号从小到大的顺序平行于坐标轴先后铺设,后铺的地毯覆盖在前面已经铺好的地毯之上。

地毯铺设完成后,组织者想知道覆盖地面某个点的最上面的那张地毯的编号。注意:在矩形地毯边界和四个顶点上的点也算被地毯覆盖。

输入格式

输入共 n+2 行。

第一行,一个整数 n,表示总共有 n 张地毯。

接下来的 n 行中,第 i+1 行表示编号 i 的地毯的信息,包含四个整数 a,b,g,k,每两个整数之间用一个空格隔开,分别表示铺设地毯的左下角的坐标 (a,b) 以及地毯在 x 轴和 y 轴方向的长度。

第 n+2 行包含两个整数 x 和 y,表示所求的地面的点的坐标 (x,y)。

输出格式

输出共 11 行,一个整数,表示所求的地毯的编号;若此处没有被地毯覆盖则输出 -1

输入输出样例

输入:                        输出:
3                             3
1 0 2 3
0 2 3 3
2 1 3 3
2 2

-------------------------------------------------------

3                            -1
1 0 2 3
0 2 3 3
2 1 3 3
4 5

数据范围

对于30%的数据,有 n≤2。
对于50%的数据,0≤≤a,b,g,k≤1000。
对于100%的数据,有 0≤n≤10000, 0≤a,b,g,k≤1000000。

=========================================================================

 二、讲解

首先,要能耐下心去读题,题目不难,但是字多。

根据读题,要能发现几个点。第一个,把区域看作第一象限;第二个,编号从1开始;第三个,重合的区域是编号低的在下面;第四个,边界;第五个,数据范围。尤其是数据范围要特别注意。

在开始写代码的时候,我们还要去想想这个情景中的一些特殊的情况,就比如:所求的地面被覆盖的地毯编号是怎么算(这里的算不是要计算,所求的地面正好被多个地毯覆盖,输出哪个编号的地毯,是最上面的,最下面的还是按照某个规律进行输入)?

根据题目,我们知道输出的是最上面的地毯编号。

通过上面对问题的一系列的细节检索和自我提问,让我们对这个题目理解了一大部分。现在开始一步步的编写代码即可。

三、代码逐步编写

1、对一开始所需要的各种变量进行定义。根据输出的是最上面的地毯编号,一开始我是想一组一组的判断然后将最上边的编号记录下来,但是x,y是在a,b,g,k的下面输入的,所以这种的话,没有判断的条件,所以我决定用数组进行储存起来。

#include<stdio.h>
int arr[10000][4];//储存地毯的信息
int main()
{
    int n;
    int a, b, g, k;//地毯左下角的横坐标和纵坐标,地毯在横向上的长度和在纵向上的长度
    scanf("%d", &n);
    int flag = -1;//记录地毯的编号
    int i = 0;//既是循环变量又相当于是地毯的数量
    for (i = 0; i < n; i++)
    {
        scanf("%d%d%d%d", &a, &b, &g, &k);
        arr[i][0] = a;
        arr[i][1] = b;
        arr[i][2] = g;
        arr[i][3] = k;
    }
    int x, y;//所求地面
    scanf("%d%d", &x, &y);
    return 0;
}

 2、开始进行条件的判断。

对下面注释进行解释 

1)进行判断某个点是否在一个区域里,只需要看x,y是否在相对应的x和y的范围里面

这样画图看的话,是不是只要点的横坐标在2和2+3之间,纵坐标在3和3+3之间就相当于点在区域的里面。将这样的关系转化为代码即可。(注意的是边界值,如果点在地毯的边上,角上也算作覆盖,所以有等号哦

#include<stdio.h>
int arr[10000][4];//储存地毯的信息
int main()
{
    int n;
    int a, b, g, k;//地毯左下角的横坐标和纵坐标,地毯在横向上的长度和在纵向上的长度
    scanf("%d", &n);
    int flag = -1;//记录地毯的编号
    int i = 0;//既是循环变量又相当于是地毯的数量
    for (i = 0; i < n; i++)
    {
        scanf("%d%d%d%d", &a, &b, &g, &k);
        arr[i][0] = a;
        arr[i][1] = b;
        arr[i][2] = g;
        arr[i][3] = k;
    }
    int x, y;//所求地面
    scanf("%d%d", &x, &y);
    i--;//找到储存最后一块地毯的数组下标
    for (i; i >= 0; i--)
    {
        //进行判断某个点是否在一个区域里,只需要看x,y是否在相对应的x和y的范围里面
        if (x >= arr[i][0] && x <= (arr[i][0] + arr[i][2]))
        {
            if (y >= arr[i][1] && y <= (arr[i][1] + arr[i][3]))
            {
                flag = i;
                break;
            }
        }
    }
    if (flag == -1)
        printf("-1");
    else
        printf("%d", flag + 1);//因为flag里面存的是数组下标,下标是从0开始的,而地毯编号是从1开始的,所以要+1
    return 0;
}

给个三连吧!!!谢谢咯。

  • 22
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 20
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 20
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

仍有未知等待探索

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值