码迷,mamicode.com
首页 > 其他好文 > 详细

Percolation

时间:2015-02-09 17:51:37      阅读:648      评论:0      收藏:0      [点我收藏+]

标签:

报了coursera的algorithms, part I课程,第一周的编程作业是Percolation。做出来并不难,但就是有一个backwash的情况。刚开始想用两个UF实例做,但是checklists里明显说了可以用一个UF实例完成,百思不得其解。搜索discussion forum发现http://tech-wonderland.net/blog/avoid-backwash-in-percolation.html这里讲了如何用一个UF解决backwash的思路,循着思路终于写出了代码。

 1 public class Percolation {
 2     // 0: block 1: open 2: connected to top 4: connected to bottom
 3     private byte[] lattice;
 4     private WeightedQuickUnionUF uf;
 5     private int size;
 6     private boolean percolate;
 7     
 8     public Percolation(int N) {
 9         if (N <= 0) throw new java.lang.IllegalArgumentException();
10         size = N;
11         uf = new WeightedQuickUnionUF(N*N);
12         lattice = new byte[N*N];
13         percolate = false;
14     }
15     
16     public void open(int i, int j) {
17         validate(i, j);
18         int position = xyTo1D(i, j);
19         if ((lattice[position] & 1) == 0) {
20             int uPosition = xyTo1D(i-1, j);
21             int dPosition = xyTo1D(i+1, j);
22             int lPosition = xyTo1D(i, j-1);
23             int rPosition = xyTo1D(i, j+1);
24             if (dPosition >= size*size)
25                 dPosition = -1;
26             if (j == 1)
27                 lPosition = -1;
28             if (j == size)
29                 rPosition = -1;
30             int[] positions = {uPosition, dPosition, lPosition, rPosition};
31             int[] stats = new int[4];
32             for (int idx = 0; idx < 4; idx++) {
33                 int p = positions[idx];
34                 if ((p >= 0) && ((lattice[p] & 1) == 1)) {
35                     stats[idx] = lattice[uf.find(p)];
36                     uf.union(position, p);
37                 }
38             }
39             int root = uf.find(position);
40             for (int idx = 0; idx < 4; idx++) {
41                 lattice[root] |= stats[idx];
42             }
43             lattice[position] |= 1;
44             if (i == 1) lattice[root] |= 2;
45             if (i == size) lattice[root] |= 4;
46             if ((lattice[root] & 7) == 7) percolate = true;           
47         }
48     }
49     
50     public boolean isOpen(int i, int j) {
51         validate(i, j);
52         return (lattice[xyTo1D(i, j)] & 1) == 1;
53     }
54     
55     public boolean isFull(int i, int j) {
56         validate(i, j);
57         return (lattice[uf.find(xyTo1D(i, j))] & 3) == 3;
58     }
59     
60     public boolean percolates() {
61         return percolate;
62     }
63     
64     private void validate(int i, int j) {
65         if (i < 1 || i > size || j < 1 || j > size)
66             throw new java.lang.IndexOutOfBoundsException();
67     }
68     
69     private int xyTo1D(int i, int j) {
70         return (i - 1) * size + j - 1;
71     }
72 }

代码可能比较丑,好久没写过Java代码,都忘记了,数组都不知道怎么初始化。这个方法与利用虚拟格子的方式不同,它将lattice是否percolate的信息存储在了每个联通分量的根节点中。也许事先什么都不知道直接来实现percolate更容易想到这个方法,但如果一直记着虚拟格子,反而更难拓宽思路。还有代码中lattice用byte类型,这样可以使代码的内存使用量大概为9N^2bytes,如果使用int的话就得12N^2,这样就拿不到bonus的分数了。当然其实每个格子4bit就可以存储状态了,但没有那么严格的要求,用byte也就可以了。

Percolation

标签:

原文地址:http://www.cnblogs.com/angwer/p/4282007.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!