zoukankan      html  css  js  c++  java
  • 【USACO 3.1.4】形成的区域

    【描述】

              N个不同的颜色的不透明的长方形(1 <= N <= 1000)被放置在一张宽为A长为B的白纸上。
    这些长方形被放置时,保证了它们的边于白纸的边缘平行。
    所有的长方形都放置在白纸内,所以我们会看到不同形状的各种颜色。(颜色用[1,1000]内的整数表示)
    坐标系统的原点(0,0)设在这张白纸的左下角,而坐标轴则平行于边缘。
     

    【格式】

    PROGRAM NAME: rect1
    INPUT FORMAT:(file rect1.in)
     
    每行输入的是放置长方形的方法。
    第一行输入的是那个放在底的长方形(即白纸)。
    第 1 行: A , B 和 N, 由空格分开 (1 <=A, B<=10,000)
    第 2 到N+1行: 为五个整数 llx, lly, urx, ury, color 这是一个长方形的左下角坐标,右上角坐标和颜色。
    颜色 1和底部白纸的颜色相同。
     
    OUTPUT FORMAT:(file rect1.out)

    输出文件应该包含一个所有能被看到颜色连同该颜色的总面积的清单( 即使颜色的区域不是连续的),按color的增序顺序。
    不要显示没有区域的颜色。

    【分析】

    本来想用离散化的,结果发现会超时...

    借鉴了一个很好的思想,漂浮法。

    漂浮法:以逆序来进行放置,即n to 1。逆序的好处在于放置一个矩形后,俯视看到的就是最终俯视该矩形应该看到的。因为挡着它的矩形在之前已经放置好了,所以可直接统计,为递归创造了条件。每放一个矩形,可以想象成将其扔入一密度很大的海水底部,海分成了n层,然后矩形开始向上浮。在上浮过程中若碰撞到其他的矩形则断裂成几个小矩形,继续上浮,直到浮出水面。用递归来模拟上浮过程。

     1 #include <cstdlib>
     2 #include <iostream>
     3 #include <cstdio>
     4 #include <cstring>
     5 #include <cmath>
     6 #include <algorithm>
     7 const int maxn=1000+20;
     8 using namespace std;
     9 int lx[maxn],ly[maxn],rx[maxn],ry[maxn];
    10 int color[maxn]={1},S[2501],N;
    11 //前四个为矩形的坐标颜色 
    12 void cover(int x1,int y1,int x2,int y2,int c,int h)
    13 {
    14     if (x1==x2 || y1==y2) return;//去掉面积为0的矩阵 
    15     if (h>N) S[c]+=(y2-y1)*(x2-x1);
    16     else
    17     {
    18         //断裂成四个小矩形 
    19         if (y1<ly[h]) cover(min(rx[h],x1),y1,min(rx[h],x2),min(ly[h],y2),c,h+1);
    20         if (x2>rx[h]) cover(max(rx[h],x1),min(ry[h],y1),x2,min(ry[h],y2),c,h+1);
    21         if (y2>ry[h]) cover(max(lx[h],x1),max(ry[h],y1),max(lx[h],x2),y2,c,h+1);
    22         if (x1<lx[h]) cover(x1,max(ly[h],y1),min(lx[h],x2),max(ly[h],y2),c,h+1);
    23     }
    24 }
    25 int main()
    26 {
    27     int i;
    28     //文件操作
    29     freopen("rect1.in","r",stdin);
    30     freopen("rect1.out","w",stdout); 
    31     
    32     scanf("%d%d%d",&rx[0],&ry[0],&N);//白纸 
    33     for (i=1;i<=N;i++) scanf("%d%d%d%d%d",&lx[i],&ly[i],&rx[i],&ry[i],&color[i]);
    34     
    35     S[color[N]]+=(rx[N]-lx[N])*(ry[N]-ly[N]);//最后一张纸 
    36     
    37     for (i=N-1;i>=0;i--) cover(lx[i],ly[i],rx[i],ry[i],color[i],i+1);
    38     for (i=1;i<=maxn;i++) if (S[i]!=0) printf("%d %d
    ",i,S[i]);
    39     return 0;
    40 }
  • 相关阅读:
    题目1.A乘以B
    题目1.A乘以B
    秋季学习总结
    题目1.A乘以B
    第一周作业
    C语言I博客作业02
    Silverlight中图像的变换(1)
    SQL SERVER 2005安装过程中COM+错误解决!
    c++ 对文件的操作
    JS标准DES加解密
  • 原文地址:https://www.cnblogs.com/hoskey/p/3803145.html
Copyright © 2011-2022 走看看