zoukankan      html  css  js  c++  java
  • 一个蒟蒻的解题过程记录——洛谷P1003 铺地毯

    这到题算是我“火线回归”后码的第一道题,病好了心情不错,发篇博客分享一下

    目录:

    ·题目描述

    ·题目分析

    ·解题思路

    ·代码实现

    ·总结


     

    ·题目描述:

      为了准备一场特殊的颁奖典礼,组织者在会场的一片矩形区域(可看做是平面直角坐标系的第一象限)铺上一些矩形地毯。一共有n张地毯,编号从1到n。现在将这些地毯按照编号从小到大的顺序平行于坐标轴先后铺设,后铺的地毯覆盖在前面已经铺好的地毯之上。地毯铺设完成后,组织者想知道覆盖地面某个点的最上面的那张地毯的编号。注意:在矩形地毯边界和四个顶点上的点也算被地毯覆盖

    ·题目分析:

      这道题看上去是一道很水很水的模拟题,一般人的第一思路就是套上三层循环,用一个二维数组模拟会场的每一块地板。不错, 我一开始也是这样想的,代码如下:

     1 #include<cstdio>
     2 #include<iostream>
     3 
     4 using namespace std;
     5 
     6 int n;
     7 int a,b,g,k,xx,yy;
     8 int ground[10010][10010]={-1};//赋值为-1的目的是如果没有被赋值,就可以直接输出-1,不用再判断了(其实就是懒)
     9 
    10 int main()
    11 {
    12     scanf("%d",&n);
    13     for(int i=1;i<=n;++i)
    14     {
    15         scanf("%d%d%d%d",&a,&b,&g,&k);//没有用数组,再每次输入的同时进行处理(用了数组之后的效果不如这样处理好)
    16         for(int j=a;j<=a+g;++j)
    17             for(int n=b;n<=b+k;++n)//又是两层循环,将每一块受到影响的(既需要更新的)地板的坐标进行枚举
    18                 ground[j][n]=i;//将这块地板附上最后一次赋值的值(模拟的是最上面的一块地毯)
    19     }
    20     scanf("%d%d",&xx,&yy);
    21     printf("%d",ground[xx][yy]);//直接查找需要查找的地板最上面是那一块地毯
    22     return 0;
    23 }

      是的,这道题看上去很水,上面的代码看似完美无缺。但是结果是这样的:

      

      是的,就是149.79s

      

      所以,是什么导致了这种结果的发生呢???于是,我不要脸的点开了题解

      原来,按照我的做法似是肯定会MLE的,因为这道题很坑,出题人的目的就是让我们将数据从前往后读入,再从后往前循环,从而求解(具体解题思路请继续往下看)

    ·解题思路:

      根据上面的结论,我们可以找到一个更快、更优、更好的算法。

      先将第2~n+1行的数据读入,存到一个二维数组中,然后从n~1枚举每一组数据,查看第一个包括需要查询的点的地毯。如果有,就直接输出这个地毯的编号,结束程序;如果没有,就输出“-1”,同样结束程序;

    ·代码实现:

      说了这么多,没有代码怎么能行呢???

     1 #include<cstdio>
     2 #include<iostream>
     3 
     4 using namespace std;
     5 
     6 int shuju[10010][5];//定义一个“数据”数组,用来读入每一组数据
     7 int n,xx,yy;
     8 
     9 int main()
    10 {
    11     scanf("%d",&n);
    12     for(int i=1;i<=n;++i)
    13         for(int j=1;j<=4;++j)
    14             scanf("%d",&shuju[i][j]);//读入数据ing
    15     scanf("%d%d",&xx,&yy);
    16     for(int i=n;i>=1;i--)//从n~1循环
    17     {
    18         if((shuju[i][1]<=xx)&&(shuju[i][3]+shuju[i][1]>=xx)&&(shuju[i][2]<=yy)&&(shuju[i][2]+shuju[i][4]>=yy))//判断要找的点是否再这个地毯内 
    19         {
    20             printf("%d",i);//如果有,就输出该点的编号
    21             return 0;//直接结束程序
    22         }
    23     }
    24     printf("-1");//如果没有,就输出-1
    25     return 0;//还是结束程序
    26 }

    ·总结:

      这道题还是很坑的,因为这道题不是单纯无脑的模拟,而是运用到了某种类似于“逆推还原”的思想,思路并不是很好想。所以在以后的解题过程当中,不要想当然,一定要仔细斟酌,然后就能AC啦!

  • 相关阅读:
    WCF+Silverlight 制作一个简单RSS的阅读器(一)
    将Ironpython嵌入到你的程序中
    今天修改了网页
    开发小议
    Silverlight 可以支持windows2000了
    昨天晚上开始寻找圣诞的素材了
    需要每天的坚持!
    今天开始学习ADO.NET中的Connection对象(一)SqlConnection对象连接SQL Server
    一个基于Ajax简单的数据验证
    《微软:DirectShow开发指南》第4章 Capturing Audio with DirectShow
  • 原文地址:https://www.cnblogs.com/juruohqk/p/11014101.html
Copyright © 2011-2022 走看看