# 程序员死后的世界简单攻略

A题比较有意思，是一道NP问题。

  1 #include <cstdio>
2 #include <cstdlib>
3 #include <ctime>
4 #include <queue>
5 #include <utility>
6 #include <algorithm>
7
8 using namespace std;
9 typedef long long ll;
10 const int N = 105;
11 const int dx[] = {0, 1, 0, -1};
12 const int dy[] = {1, 0, -1, 0};
13
14 struct Buildings {
15     int h, w, r, c, id;
16     int size;
17
18     inline void get(int _id) {
19         scanf("%d%d%d%d", &h, &w, &r, &c);
20         id = _id;
21         size = h * w;
22     }
23
24     inline bool operator < (const Buildings b) const {
25         return h * w > b.h * b.w;
26     }
27 } building[N];
28
29 queue <pair<int, int> > q;
30 int H, W, n, cnt, TOT, a[N][N], vis[N][N], ans[N][N], mx;
31 int totalSize;
32
33 inline bool in(int x, int y) {
34     return 1 <= x && x <= H && 1 <= y && y <= W;
35 }
36
37 bool check(int x, int y, int h, int w, int id, int r, int c) {
38     if (a[r][c]) return 0;
39     for (int i = 0; i < h; ++i)
40         for (int j = 0; j < w; ++j)
41             if (a[x + i][y + j]) return 0;
42     for (int i = 0; i < h; ++i)
43         for (int j = 0; j < w; ++j)
44             a[x + i][y + j] = id;
45
46     while (!q.empty()) q.pop();
47     q.push(make_pair(r, c));
48     vis[r][c] = ++TOT;
49     int tmp = 0;
50     int nowX, nowY, X, Y;
51     while (!q.empty()) {
52         if (tmp == cnt) {
53             a[r][c] = -1;
54             return ++cnt;
55         }
56         nowX = q.front().first, nowY = q.front().second;
57         q.pop();
58         for (int i = 0; i < 4; ++i) {
59             X = nowX + dx[i], Y = nowY + dy[i];
60             if (in(X, Y) && a[X][Y] <= 0 && vis[X][Y] != TOT) {
61                 vis[X][Y] = TOT;
62                 if (a[X][Y] == -1) ++tmp;
63                 q.push(make_pair(X, Y));
64             }
65         }
66     }
67     for (int i = 0; i < h; ++i)
68         for (int j = 0; j < w; ++j)
69             a[x + i][y + j] = 0;
70     return 0;
71 }
72
73 void update() {
74     int tmp = 0;
75     for (int i = 1; i <= H; ++i)
76         for (int j = 1; j <= W; ++j)
77             tmp += (a[i][j] > 0);
78     if (tmp <= mx) return;
79     mx = tmp;
80     for (int i = 1; i <= H; ++i)
81         for (int j = 1; j <= W; ++j)
82             ans[i][j] = a[i][j];
83 }
84
85 inline bool random_(int sz) {
86     //return 1ll * rand() * rand() % totalSize > building[1].size - sz / 2;
87     return rand() % sz > sz - 3;
88 }
89
90 int main() {
91     int h, w, r, c, id;
92     srand(time(0));
93     scanf("%d%d%d", &H, &W, &n);
94     for (int i = 1; i <= n; ++i) {
95         building[i].get(i);
96         totalSize += building[i].size;
97     }
98     sort(building + 1, building + n + 1);
99     for (int set = 0; set < 256; set++) {
100         cnt = 0;
101         for (int i = 1; i <= H; ++i)
102             for (int j = 1; j <= W; ++j)
103                 a[i][j] = 0;
104         for (int i = 1; i <= n; ++i) {
105             if (random_(building[i].size)) {
106                 //printf("%d Done %d\n", i, set);
107                 continue;
108             }
109             h = building[i].h;
110             w = building[i].w;
111             r = building[i].r;
112             c = building[i].c;
113             id = building[i].id;
114             if (r == 1) {
115                 for (int x = H - h + 1; x > 1; --x) {
116                     if (set & 1) {
117                         for (int y = 1; y <= W - w + 1; y++)
118                             if (check(x, y, h, w, id, x - 1, y + c - 1))
119                                 goto end;
120                     } else {
121                         for (int y = W - w + 1; y >= 1; y--)
122                             if (check(x, y, h, w, id, x - 1, y + c - 1))
123                                 goto end;
124                     }
125                 }
126             } else
127             if (r == h) {
128                 for (int x = 1; x <= H - h; ++x) {
129                     if (set & 2) {
130                         for (int y = 1; y <= W - w + 1; y++)
131                             if (check(x, y, h, w, id, x + r, y + c - 1))
132                                 goto end;
133                     } else {
134                         for (int y = W - w + 1; y >= 1; y--)
135                             if (check(x, y, h, w, id, x + r, y + c - 1))
136                                 goto end;
137                     }
138                 }
139             } else
140             if (c == 1) {
141                 for (int y = W - w + 1; y > 1; y--) {
142                     if (set & 4) {
143                         for (int x = 1; x <= H - h + 1; x++)
144                             if (check(x, y, h, w, id, x + r - 1, y - 1))
145                                 goto end;
146                     } else {
147                         for (int x = H - h + 1; x >= 1; x--)
148                             if (check(x, y, h, w, id, x + r - 1, y - 1))
149                                 goto end;
150                     }
151                 }
152             } else {
153                 for (int y = 1; y <= W - w; y++) {
154                     if (set & 8) {
155                         for (int x = 1; x <= H - h + 1; x++)
156                             if (check(x, y, h, w, id, x + r - 1, y + c))
157                                 goto end;
158                     } else {
159                         for (int x = H - h + 1; x >= 1; x--)
160                             if (check(x, y, h, w, id, x + r - 1, y + c))
161                                 goto end;
162                     }
163                 }
164             }
165             end: ;
166         }
167         update();
168     }
169     for (int i = 1; i <= H; ++i)
170         for (int j = 1; j <= W; ++j)
171             printf("%d%c", max(ans[i][j], 0), j == W ? '\n' : ' ');
172     return 0;
173 }
View Code

p.s.有谁知道最后那个换装到底怎么搞，请在下面留言，谢谢，我是真看不太懂日文。。。

posted on 2019-02-14 20:10  Xs酱~  阅读(...)  评论(...编辑  收藏