UVA11846-Finding Seats Again(DFS)

Problem UVA11846-Finding Seats Again

Accept: 69    Submit: 433
Time Limit: 10000 mSec

Problem Description

A set of n2 computer scientists went to the movies. Fortunately, the theater they chose has a square layout: n rows, each one with n seats. However, these scientists are not all from the same research area and they want to seat together. Indeed, there are K independent research groups of scientists among them (no scientist belongs to two of them) with a distiguished leader for each group. Then the leader bought the tickets for his whole group, and he did it in such a way that all his group could seat occupying a rectangular set of seats (and everyone in this set of seats belongs to the same group). Every group was placed satisfying this bizarre condition, although the scientists did not care where the actual assigned areas were. The usher was informed of the situation and he decided to annotate in a theater map a satisfactory seats deploying. He thought that if he wrote the position of each group’s leader in the map indicating besides the corresponding group size, he could tell where to accomodate every scientist. But he discovered that it is not so easy! The usher asks for your help. You must tell him a way to place the K rectangular areas with the given sizes, and with the corresponding leader for each group seated where it was originally assigned.

 

Input

Input consists of several test cases, each one defined by a set of lines:

• the first line in the case contains two numbers n and K separated by blanks, with n representing the size of the theater (0 < n < 20) and K the number of groups (K ≤ 26);

• the next n lines describe the usher’s map. A one-digit decimal number in the map indicates the seat of a leader and the size of his group. A point indicates that no leader will sit there.
The end of the input is indicated by the line
0 0

 Output

For each test case, display an answer consisting in n lines each one of them with n characters representing a seat occupation for the theater. Each group is assigned to an uppercase letter and all of its members are identified with that letter. No two groups are assigned to the same letter.

 

 Sample Input

3 3
3.4
...
.2.
7 18
...4.2.
...45..
222..3.
...2..3
.24...2
...2.3.
22..3..
0 0
 

 Sample Output

ABB
ABB
ACC
AAAABCC
DDDDBEF
GHIIBEF
GHJKBEF
LLJKBMM
NOJPQQQ
NOJPRRR

 

题解:这个题还是挺有价值的,看到这个题目,第一时间想到了UVA211的那个多米诺效应那个题,但是这两个题除了题意有点相似之外感觉就没啥相同的了(虽然都是DFS),一开始的思路围绕是数字的格子展开,这个思路在填字母的时候就有很大的困难,这个是数字的格子位于这个矩形的哪里,这个矩形的长宽分别是多少,这两个问题使得这个思路几乎就行不通了。最后参考了大佬的题解(orz),发现他不是从是数字的格子开始扩展,而是直接顺着从没有填过字母的格子开始扩展,扩展的范围很清楚,就是先枚举行,再枚举列,对于枚举中一个给定的矩形,首先这里不能有字母,其次有且仅有一个数字,并且数字的大小等于矩形的面积,满足了这些,就是一个可以继续深层递归的状态,接着dfs下去。这里在枚举的过程中有一个不错的减少枚举的方法,就是如果先枚举行,那么列的最大值随着行的增加一定是不增的(原因很简单,详见代码),这样就可以随时改变列的最大值从而减少枚举。

 

 1 #include <bits/stdc++.h>
 2 
 3 
 4 using namespace std;
 5 
 6 const int maxn = 25;
 7 const int  INF = 0x3f3f3f3f;
 8 
 9 int n, k;
10 char gra[maxn][maxn], ans[maxn][maxn];
11 
12 bool dfs(int id, char ch) {
13     while (ans[id / n][id % n] != '.') id++;
14     if (id == n * n) return true;
15 
16     int sr = id / n, sc = id % n, ec = n;
17     for (int r = sr; r < n; r++) {
18         for (int c = sc; c < ec; c++) {
19             if (ans[r][c] != '.') { ec = c; break; }
20             int sum = (r - sr + 1)*(c - sc + 1);
21             int num = INF;
22             bool ok = true;
23             for (int i = sr; i <= r; i++) {
24                 for (int j = sc; j <= c; j++) {
25                     if (isdigit(gra[i][j])) {
26                         if (num != INF) { ok = false; break; }
27                         else num = gra[i][j] - '0';
28                     }
29                 }
30                 if (!ok) break;
31             }
32             if (!ok || sum > num) { ec = c; break; }
33             if (sum < num) continue;
34             
35             for (int i = sr; i <= r; i++) {
36                 for (int j = sc; j <= c; j++) {
37                     ans[i][j] = ch;
38                 }
39             }
40             if (dfs(id + c - sc + 1, ch + 1)) return true;
41             for (int i = sr; i <= r; i++) {
42                 for (int j = sc; j <= c; j++) {
43                     ans[i][j] = '.';
44                 }
45             }
46         }
47     }
48     return false;
49 }
50 
51 int main()
52 {
53     //freopen("input.txt", "r", stdin);
54     while (~scanf("%d%d", &n, &k) && (n || k)) {
55         for (int i = 0; i < maxn; i++) {
56             for (int j = 0; j < maxn; j++) {
57                 ans[i][j] = '.';
58             }
59         }
60         for (int i = 0; i < n; i++) {
61             scanf("%s", gra[i]);
62         }
63 
64         dfs(0, 'A');
65 
66         for (int i = 0; i < n; i++) {
67             for (int j = 0; j < n; j++) {
68                 printf("%c", ans[i][j]);
69             }
70             printf("\n");
71         }
72     }
73     return 0;
74 }

 

posted on 2018-09-07 16:09  随缘&不屈  阅读(532)  评论(0编辑  收藏  举报

导航