[Offer收割]编程练习赛12 题目3 : 矩形分割

时间限制:10000ms

单点时限:1000ms

内存限制:256MB

描述

小Hi有一块由NxM个单位正方形组成的矩形。现在小Ho在某些单位正方形上画了一道分割线,这条分割线或者是单位正方形的主对角线(用‘\‘表示),或者是副对角线(用‘/‘表示)。

现在小Hi想知道这些分割线把NxM的矩形分割成了多少块区域。

例如

/\/

就把2x2的矩形分成了5个区域。

/\/\  /
 \/

把3x4的矩形分成了7个区域。

输入

第一包含两个整数N和M。(1 <= N, M <= 100)

以下N行每行包含M个字符。每个字符只可能是/\或者空格。

输出

分割成的区域数目。

样例输入
3 4
/\/\
\  /
 \/\
样例输出
7

思路

(1)并查集。将每个位置用主对角线和反对角线分割成4块,以每一小块看做一个元素,利用并查集求解即可。

(2)DFS,BFS。分割方法与(1)相同,然后从每个未访问过的位置搜索、标记即可。

代码

 1 import java.util.Scanner;
 2
 3 public class Main {
 4
 5     static class UF {
 6         int[] parent;
 7         int count;
 8
 9         public UF(int n) {
10             count = n;
11             parent = new int[n];
12             for (int i = 0; i < n; i++) {
13                 parent[i] = i;
14             }
15         }
16
17         public int find(int id) {
18             while (parent[id] != id) {
19                 parent[id] = parent[parent[id]];
20                 id = parent[id];
21             }
22             return id;
23         }
24
25         public void union(int pid, int qid) {
26             int proot = find(pid);
27             int qroot = find(qid);
28             if (proot != qroot) {
29                 parent[proot] = qroot;
30                 count--;
31             }
32         }
33     }
34
35     public static void main(String[] args) {
36         Scanner sc = new Scanner(System.in);
37         int m = sc.nextInt();
38         int n = sc.nextInt();
39         sc.nextLine();
40         char[][] b = new char[m][];
41         for (int i = 0; i < m; i++) {
42             b[i] = sc.nextLine().toCharArray();
43         }
44
45         UF uf = new UF(n * m * 4);
46         for (int i = 0; i < m; i++) {
47             for (int j = 0; j < n; j++) {
48                 int id = 4 * (i * n + j);
49                 if (b[i][j] == ‘/‘ || b[i][j] == ‘ ‘) {
50                     uf.union(id, id + 1);
51                     uf.union(id + 2, id + 3);
52                 }
53
54                 if (b[i][j] == ‘\\‘ || b[i][j] == ‘ ‘) {
55                     uf.union(id, id + 3);
56                     uf.union(id + 1, id + 2);
57                 }
58
59                 if (j > 0)
60                     uf.union(id, id - 2);
61                 if (i > 0)
62                     uf.union(id + 1, id - 4 * n + 3);
63                 if (j < n - 1)
64                     uf.union(id + 2, id + 4);
65                 if (i < m - 1)
66                     uf.union(id + 3, id + 4 * n + 1);
67             }
68         }
69         System.out.println(uf.count);
70     }
71 }
时间: 2024-10-15 08:54:31

[Offer收割]编程练习赛12 题目3 : 矩形分割的相关文章

[Offer收割]编程练习赛12 题目4 : 寻找最大值

时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 给定N个数A1, A2, A3, ... AN,小Ho想从中找到两个数Ai和Aj(i ≠ j)使得乘积Ai × Aj × (Ai AND Aj)最大.其中AND是按位与操作. 小Ho当然知道怎么做.现在他想把这个问题交给你. 输入 第一行一个数T,表示数据组数.(1 <= T <= 10) 对于每一组数据: 第一行一个整数N(1<=N<=100,000) 第二行N个整数A1, A2, A3, ... AN

[Offer收割]编程练习赛12 题目1 : 歌德巴赫猜想

时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 哥德巴赫猜想认为"每一个大于2的偶数,都能表示成两个质数之和". 给定一个大于2的偶数N,你能找到两个质数P和Q满足P<=Q并且P+Q=N吗? 输入 一个偶数N(4 <= N <= 1000000) 输出 输出P和Q.如果有多组解,输出P最小的一组. 样例输入 10 样例输出 3 7 思路 判断和为N两个数是否为素数 代码 1 import java.util.Scanner; 2 3 pu

[Offer收割]编程练习赛12 题目2 : 一面砖墙

时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi的学校的教学楼前有一面砖墙.这面墙由N层砖砌成,其中从上到下第i层包含Ci块高度相同但宽度不同的砖. 例如下图所示的这面墙,由3层砖砌成.其中第1层包含3块砖,从左到右宽度依次是6.4和3:第2层包含4块砖,从左到右依次宽度依次是4.4.2和3:第3层包含3块砖,从左到右宽度依次是5.6和2. +------------+ | 6 | 4 |3 | +------------+ | 4 | 4 |2|3 | +-

hihocoder offer收割编程练习赛12 C 矩形分割

思路: 模拟,深搜. 实现: 1 #include <iostream> 2 #include <cstdio> 3 #include <string> 4 using namespace std; 5 6 const int dx[4] = { 0, 1, 0, -1 }; 7 const int dy[4] = { -1, 0, 1, 0 }; 8 9 int n, m, cnt = 0; 10 int a[305][305]; 11 bool vis[305][3

hihocoder offer收割编程练习赛12 D 寻找最大值

思路: 可能数据太水了,随便乱搞就过了. 实现: 1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 using namespace std; 5 typedef long long ll; 6 7 int a[100005], n; 8 9 int main() 10 { 11 int t; 12 cin >> t; 13 while (t--) 14 { 15 ll max

hihocoder offer收割编程练习赛12 A 歌德巴赫猜想

思路: 枚举. 实现: 1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 using namespace std; 5 6 const int MAX_N = 1000005; 7 8 int prime[MAX_N]; 9 bool is_prime[MAX_N + 1]; 10 11 int init(int n) 12 { 13 int p = 0; 14 for (int i =

[Offer收割]编程练习赛11 题目2 : 物品价值

时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi现在有n个物品,每个物品都有一个价值.并且这n个物品总共有m个不同的属性,每个物品都具有其中若干属性. 小Ho要从中选出若干物品,满足每个属性都正好有奇数个物品拥有,且被选出的物品价值总和最大.你能帮助小Ho完成任务么? 输入 第一行一个数T(<=10),表示数据组数.对于每一组数据: 第一行两个数n,m(1<=n<=1000,m<=10) 接下来每两行描述一件物品.对于每一件物品: 第一行两个数v

[Offer收割]编程练习赛11 题目3 : 岛屿3

时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 H国正在进行一项持续N周的填海造岛工程.整片工程海域可以被看作是1000x1000的网格. 每周都有一块1x1的单位方格海域被填成陆地.如果我们将连成一片的陆地(一块单位方格与它上下左右4个单位方格是相连的)视为岛屿,H国想监测每周末整片海域中一共存在有多少个岛屿,以及这些岛屿的总面积和总周长各是多少. 假设工程持续三周,第一周被填的海域坐标是(0, 0),那么第一周结束后有1座岛屿.总面积是1.总周长是4: #..

[Offer收割]编程练习赛11 题目1 : hiho字符串

时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 如果一个字符串恰好包含2个'h'.1个'i'和1个'o',我们就称这个字符串是hiho字符串. 例如"oihateher"."hugeinputhugeoutput"都是hiho字符串. 现在给定一个只包含小写字母的字符串S,小Hi想知道S的所有子串中,最短的hiho字符串是哪个. 输入 字符串S 对于80%的数据,S的长度不超过1000 对于100%的数据,S的长度不超过100000 输