USACO 3.1.4 Shaping Regions

本文详细解析了一种基础的矩形切割算法,并通过一个具体的示例进行说明。该算法涉及如何处理矩形间的交叠部分,包括如何切割矩形以避免重叠区域,并计算各颜色矩形的面积。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

比较基础的矩形切割。

POJ 2528 Mayor's posters的二维版。

还是要注意边缘的情况,比如当(0,8)(18,18) 切割(18,0)(19,19)的时候,结果应该是得到三个矩形

(18,19)(18,19) --> 面积为1

(19,0)(19,19) --> 面积为20

(18,0)(18,7) --> 面积为8

恩,其实我一直没搞懂为啥给数据的时候llx和lly是真正的坐标值,而urx和ury却必须减一之后再用...

View Code
  1 /*
  2 ID: xjtuacm1
  3 PROG: rect1
  4 LANG: C++
  5 */
  6 #include<iostream>
  7 #include<stack>
  8 #include<cstring>
  9 #include<cstdio>
 10 #include<queue>
 11 #include<algorithm>
 12 #include<set>
 13 #include<map>
 14 #include<vector>
 15 #include<cmath>
 16 using namespace std;
 17 const int M = 100000;
 18 const int N = 1000;
 19 
 20 struct rect
 21 {
 22     int llx, lly;
 23     int urx, ury;
 24     int color;
 25     rect(int lx = 0, int ly = 0, int rx = 0, int ry = 0, int c = 0)
 26     : llx(lx), lly(ly), urx(rx), ury(ry), color(c) {}
 27 
 28     int S()
 29     {
 30         return (urx - llx + 1) * (ury - lly + 1);
 31     }
 32 }rects[M], cur;
 33 int tot;
 34 
 35 inline bool cross(const rect& r1, const rect& r2)
 36 {
 37     return !(
 38              (r1.llx > r2.urx)
 39              || (r1.urx < r2.llx)
 40              || (r1.lly > r2.ury)
 41              || (r1.ury < r2.lly));
 42 
 43 }
 44 
 45 inline void add(const rect& t)
 46 {
 47     rects[tot++] = t;
 48 }
 49 
 50 inline void del(int idx)
 51 {
 52     rects[idx] = rects[--tot];
 53 }
 54 
 55 void cut(const rect& t, bool vertical = false)
 56 {
 57     int k1, k2;
 58     rect tem = t;
 59     if(vertical)
 60     {
 61         k1 = max(t.lly, cur.lly);
 62         k2 = min(t.ury, cur.ury);
 63         if(t.lly < k1)
 64         {
 65             tem.ury = k1 - 1;
 66             add(tem);
 67         }
 68         if(k2 < t.ury)
 69         {
 70             tem = t, tem.lly = k2 + 1;
 71             add(tem);
 72         }
 73     }
 74     else
 75     {
 76         k1 = max(t.llx, cur.llx);
 77         k2 = min(t.urx, cur.urx);
 78         if(t.llx < k1)
 79         {
 80             tem.urx = k1 - 1;
 81             add(tem);
 82         }
 83         if(t.urx > k2)
 84         {
 85             tem = t, tem.llx = k2 + 1;
 86             add(tem);
 87         }
 88         tem = t, tem.llx = k1 , tem.urx = k2;
 89         cut(tem, true);
 90     }
 91 }
 92 
 93 
 94 int main(int argc, char *argv[])
 95 {
 96 #ifdef ACM_LOCAL // Local
 97     freopen("in", "r", stdin);
 98 #else
 99     #ifndef  ONLINE_JUDGE // not HDOJ / POJ
100     freopen("rect1.in", "r", stdin);
101     freopen("rect1.out", "w", stdout);
102     #endif
103 #endif
104 
105     int a, b, n;
106     scanf("%d %d %d", &a, &b, &n);
107     add(rect(0, 0, a-1, b-1, 1)); // add the white sheet first.
108 
109     while(n--)
110     {
111         scanf("%d %d %d %d %d", &cur.llx, &cur.lly, &cur.urx, &cur.ury, &cur.color);
112         cur.urx--, cur.ury--;
113 
114         for(int i = tot-1; i>= 0; i--)
115         {
116             if(cross(cur, rects[i]))
117             {
118                 cut(rects[i]);
119                 del(i);
120             }
121         }
122         add(cur);
123     }
124 
125     map<int, int> cnt;
126     for(int i = 0; i!= tot; i++)
127     {
128         cnt[rects[i].color] += rects[i].S();
129     }
130 
131     for(map<int, int>::iterator it = cnt.begin(); it!= cnt.end(); it++)
132     {
133         if(it->second)
134             printf("%d %d\n", it->first, it->second);
135     }
136 
137     return 0;
138 }

BTW, 果然学新的算法就要跟着代码一行一行调试~虽然感觉上慢了点但是可以掌握透彻~

还有,IOI国家集训队论文2004年薛茅的讲线段树跟矩形切割的,很清楚。在这里

转载于:https://www.cnblogs.com/tech-cabin/archive/2013/02/16/2913749.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值