Zeray Rice

..

[USACO 3.1] Shaping Regions

解析

…. OMG…这题是我做 USACO 以来 遇到的最蛋疼的题目..没有之一……. 刚看这题第一反应是 建个数组..一层一层模拟铺.. (水货表示什么题目第一反应就是模拟… )…但是蛋疼的 USACO 只给了 16MB 的内存.. 显然必须会超..

后来经神牛指点… 开始学 线段树 & 矩形切割 …然后用 矩形切割 AC 了…好吧

正确解法..

矩形切割.. 简单一个思路就是 建一个队列.. 将当前所有的矩形入队.. 当插入一个新的矩形的时候.. 依次和队列中的每个矩形比较.. 切割.. 将切割后的矩形入队.. 最后将插入的矩形入队… 嗯..

思路很简单… 主要蛋疼在切割的地方… 好吧 根据某个神牛的 PPT .. 先探讨一维的线段问题.. 再推广到二维的矩形问题… 但是我写的时候还是有点绕不过来… 不过最后算是勉强写完了.. 调试过完样例交了一次就AC了.. 233

几何题目什么的最!讨!厌!了!

代码

USACO 3.1 Shaping Regions raw
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
/*
USER: fanzeyia
TASK: rect1
LANG: C++
 */
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <queue>

using namespace std;

class Rect {
    private:
       struct paper {
           int llx, lly, urx, ury;
           int color;
       };
       queue<paper> q;
    public:
        Rect(int llx, int lly, int urx, int ury, int color);
        void Insert(int llx, int lly, int urx, int ury, int color);
        void Output(FILE *fin);
#ifdef __DEBUG__
        void Show();
#endif
};

Rect::Rect(int llx, int lly, int urx, int ury, int color) {
    q.push((struct paper){llx, lly, urx, ury, color});
}

void Rect::Insert(int llx, int lly, int urx, int ury, int color) {
    struct paper tmp;
    int size = q.size();
    //  切 x 方向
    for(int i = 0; i < size; i++) {
        tmp = q.front();
        q.pop();
        // 检查 x 方向
        if(tmp.ury >= lly || tmp.lly <= ury) {
            // 1. 不重叠
            if(urx <= tmp.llx || llx >= tmp.urx) {
                q.push(tmp);
                continue;
            }
            // 3. 包含
            if(llx <= tmp.llx && urx >= tmp.urx) {
                // 包含
            } else if(llx >= tmp.llx && urx <= tmp.urx) {
                // 被包含
                q.push((struct paper){tmp.llx, tmp.lly, llx, tmp.ury, tmp.color});
                q.push((struct paper){urx, tmp.lly, tmp.urx, tmp.ury, tmp.color});
                tmp.llx = llx;
                tmp.urx = urx;
            } else if((tmp.urx <= urx && tmp.urx >= llx) && tmp.llx <= llx) {
                // 2. 重叠一半..
                // 下左
                q.push((struct paper){tmp.llx, tmp.lly, llx, tmp.ury, tmp.color});
                tmp.llx = llx;
            } else if(tmp.llx <= urx && tmp.llx >= llx && tmp.urx >= urx) {
                // 下右
                q.push((struct paper){urx, tmp.lly, tmp.urx, tmp.ury, tmp.color});
                tmp.urx = urx;
            }
        }
        // 检查 y 方向
        if(urx >= tmp.llx || tmp.urx >= llx) {
            // 1. 不重叠
            if(ury <= tmp.lly || lly >= tmp.ury) {
                q.push(tmp);
                continue;
            }
            // 3. 包含
            // 包含
            if(lly <= tmp.lly && ury >= tmp.ury) {
                // 特殊情况..
                if(urx <= tmp.llx || llx >= tmp.urx) {
                    q.push(tmp);
                }
                continue;
            }
            // 被包含
            if(lly >= tmp.lly && ury <= tmp.ury) {
                q.push((struct paper){tmp.llx, ury, tmp.urx, tmp.ury, tmp.color});
                q.push((struct paper){tmp.llx, tmp.lly, tmp.urx, lly, tmp.color});
                continue;
            }
            // 2. 重叠一半..
            // 偏上
            if((tmp.lly <= ury && tmp.lly >= lly) && tmp.ury >= ury) {
                q.push((struct paper){tmp.llx, ury, tmp.urx, tmp.ury, tmp.color});
                continue;
            }
            // 偏下
            if(tmp.ury <= ury && tmp.ury >= lly && tmp.lly <= lly) {
                q.push((struct paper){tmp.llx, tmp.lly, tmp.urx, lly, tmp.color});
                continue;
            }
        }
        q.push(tmp);
    }
    q.push((struct paper){llx, lly, urx, ury, color});
}

void Rect::Output(FILE *fout) {
    int color[2501];
    int max = 0;
    struct paper tmp;
    memset(color, 0, sizeof(color));
    while(!q.empty()) {
        tmp = q.front();
        q.pop();
        color[tmp.color] += abs(tmp.urx - tmp.llx) * abs(tmp.ury - tmp.lly);
        if(tmp.color > max) {
            max = tmp.color;
        }
    }
    for(int i = 1; i <= max ; i++ ) {
        if(color[i]) {
            fprintf(fout, "%d %d\n", i, color[i]);
        }
    }
}

#ifdef __DEBUG__
void Rect::Show() {
    int size = q.size();
    int color[2501];
    int max = 0;
    struct paper tmp;
    memset(color, 0, sizeof(color));
    for(int i = 0; i < size; i++) {
        tmp = q.front();
        q.pop();
        color[tmp.color] += abs(tmp.urx - tmp.llx) * abs(tmp.ury - tmp.lly);
        printf("%d %d %d %d %d\n", tmp.llx, tmp.lly, tmp.urx, tmp.ury, tmp.color);
        if(tmp.color > max) {
            max = tmp.color;
        }
        q.push(tmp);
    }
    printf("--------[Count]--------\n");
    for(int i = 1; i <= max ; i++ ) {
        if(color[i]) {
            printf("%d %d\n", i, color[i]);
        }
    }
    printf("-----------------------\n");
}
#endif

int main() {
    FILE *fin = fopen("rect1.in", "r");
    FILE *fout = fopen("rect1.out", "w");
    int n;
    int llx, lly, urx, ury, color;
    fscanf(fin, "%d %d %d", &urx, &ury, &n);
    Rect rect(0, 0, urx, ury, 1);
#ifdef __DEBUG__
    rect.Show();
#endif
    for(int i = 0; i < n; i++) {
        fscanf(fin, "%d %d %d %d %d", &llx, &lly, &urx, &ury, &color);
        rect.Insert(llx, lly, urx, ury, color);
#ifdef __DEBUG__
        rect.Show();
#endif
    }
    rect.Output(fout);
    return 0;
}
Executing...
   Test 1: TEST OK [0.000 secs, 3188 KB]
   Test 2: TEST OK [0.000 secs, 3188 KB]
   Test 3: TEST OK [0.000 secs, 3188 KB]
   Test 4: TEST OK [0.000 secs, 3188 KB]
   Test 5: TEST OK [0.000 secs, 3188 KB]
   Test 6: TEST OK [0.000 secs, 3188 KB]
   Test 7: TEST OK [0.000 secs, 3188 KB]
   Test 8: TEST OK [0.000 secs, 3188 KB]
   Test 9: TEST OK [0.011 secs, 3188 KB]
   Test 10: TEST OK [0.011 secs, 3188 KB]
   Test 11: TEST OK [0.130 secs, 3188 KB]

All tests OK.

Comments