acm.hdu.edu.cn-1107武林采用小型项目式解决方案

武林

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 1007    Accepted Submission(s): 274


Problem Description
在一个有12行12列的方形的武林世界里,少林、武当和峨嵋三派的弟子们在为独霸武林而互相厮杀。武林世界的第一行的一列格子的坐标是(1, 1),第一行第二列坐标是(1, 2)……右下角的坐标为(12, 12)。如图:
 

少林派弟子总是在同一列回不停地行走。先往下走,走到头不能再走时就往上走,再到头则又往下走……比如,(1, 1) -> (2, 1) -> (3, 1)。
武当派弟子总是在同一行来回不停地行走。先往右走,走到头不能再走时就往左走,再到头则又往右走……比如,(2, 1) -> (2, 2) -> (2, 3)。
峨嵋派弟子总是在右下-左上方向来回不停走,先往右下方走,走到头不能再走时就往左上方走,再到头则又往右下方走……比如,(1, 1) -> (2, 2) -> (3, 3)。峨嵋弟子如果位于(1,12)或(12,1),那当然只能永远不动。

每次走动,每个弟子必须,而且只能移动一个格子。
每名弟子有内力、武艺、和生命力三种属性。这三种属性的取值范围都是大于等于0,小于等于100。

当有两名不同门派的弟子进入同一个格子时,一定会发生一次战斗,而且也只有在这种情况下,才会发生战斗。(同派弟子之间当然不会自相残杀;一个格子里三派弟子都有时,大家都会因为害怕别人渔翁得利而不敢出手;而多名同门派弟子也不会联手对付敌人,因为这有悖于武林中崇尚的单打独斗精神,会被人耻笑)

一次战斗的结果将可能导致参战双方生命力发生变化,计算方法为:

战后生命力 = 战前生命力 - 对方攻击力

而不同门派的弟子攻击力计算方法不同:

少林派攻击力 = (0.5 * 内力 + 0.5 * 武艺) * (战前生命力 + 10) / 100
武当派攻击力 = (0.8 * 内力 + 0.2 * 武艺) * (战前生命力 + 10) / 100
峨嵋派攻击力 = (0.2 * 内力 + 0.8 * 武艺) * (战前生命力 + 10) / 100

对攻击力的计算过程为浮点运算,最终结果去掉小数点后部分取整,使得攻击力总是整数。
一次战斗结束后,生命力变为小于或等于0的弟子,被视为“战死”,会从武林中消失。
两名不同门派的弟子相遇时,只发生一次战斗。

初始状态下,不存在生命值小于或等于0的弟子,而且一个格子里有可能同时有多个弟子。
一系列战斗从初始状态就可能爆发,全部战斗结束后,仍然活着的弟子才开始一齐走到下一个格子。总之,不停地战斗-行走-战斗-行走……所有弟子都需等战斗结束后,才一齐走到下一个格子。
你需要做的是,从一个初始状态,算出经过N步(N < 1000)后的状态。所有的弟子先进行完全部战斗(当然也可能没有任何战斗发生),然后再一齐走到下一个格子,这称为一步。
所有弟子总数不会超过1000。
 

Input
第一行是测试数据的组数,随后是各组测试数据。
每组数据第一行是行走步数 N。
接下来的若干行,每行描述一名弟子的位置及其各项参数。描述弟子时,格式为“弟子代号 行号 列号 内力 武艺 生命力”。弟子代号就是一个字母:
‘S’ 代表少林派弟子
‘W’ 代表武当派弟子
‘E’ 代表峨嵋派弟子

比如:
W 10 2 10 3 10
表示第10行第2列有一名武当派弟子,他的内力是 10,武艺是3,生命力是10。

每组测试数据以一个结束标志行结尾。结束标志行只含有一个字符’0’。
 

Output
针对每组测试数据,您的输出应该是4行,前3行每行是用空格分隔的两个整数,前一个是某派弟子总数,后一个是本派所有弟子生命力之和。规定第1行代表少林派,第2行代表武当派,第3行代表峨嵋派。第4行是 “***”表示结束。
 

Sample Input
2 1 S 1 2 20 20 20 W 2 1 20 20 20 0 2 S 1 2 20 20 20 W 2 1 20 20 20 E 12 12 20 20 100 0
 

Sample Output
1 20 1 20 0 0 *** 1 14 1 14 1 100 ***
 
分析得到以下类图:
以下给出项目代码:
WuLSJ.java(武林世界):
1 import java.util.ArrayList;
2 import java.util.Iterator;
3 import java.util.List;
4
5 //
6 //
7 // Generated by StarUML(tm) Java Add-In
8 //
9 // @ Project : HDU1107_WuLin
10 // @ File Name : WuLSJ.java
11 // @ Date : 2011-3-16
12 // @ Author : Nysanier
13 //
14 //
15
16 class WuLSJ { // 武林世界
17 public static final int MIN_BOUND = 1;
18 public static final int MAX_BOUND = 12;
19
20 private List<List<List<WuLDZ>>> _WuL; // 武林方阵
21
22 public void addDiZ(WuLDZ wldz) { // 加入武林弟子
23 //this._WuL[wldz.get_row()][wldz.get_col()].add(wldz);
24 this._WuL.get(wldz.get_row()).get(wldz.get_col()).add(wldz);
25 }
26
27 public void nextStat() { // 进入到下一个状态
28 // 1. 模拟当前战斗
29 for (int i = 1; i <= WuLSJ.MAX_BOUND; i++) // 遍历所有的格子
30 for (int j = 1; j <= WuLSJ.MAX_BOUND; j++) {
31 //List<WuLDZ> l = this._WuL[i][j];
32 List<WuLDZ> l = this._WuL.get(i).get(j);
33 if (l.size() == 2 && l.get(0).get_symbol() != l.get(1).get_symbol()) { // 如果一个格子里面只有两个不同门派的弟子
34 WuLDZ wldz1 = l.get(0); // 那么相互攻击
35 WuLDZ wldz2 = l.get(1);
36 l.clear(); // 两个弟子都出列
37 int g1 = wldz1.getGongJL();
38 int g2 = wldz2.getGongJL();
39 if (wldz1.beAttacked(g2) > 0) // 弟子1被攻击后未死
40 l.add(wldz1);
41 if (wldz2.beAttacked(g1) > 0) // 弟子2被攻击后未死
42 l.add(wldz2);
43 } // if
44
45 } // for
46
47
48 // 2. 进入下一个位置
49 //List<WuLDZ>[][] wlfz = this.createWLFZ(); // 创建一个新的武林方阵
50 List<List<List<WuLDZ>>> wlfz = this.createWLFZ();
51
52 for (int i = 1; i <= WuLSJ.MAX_BOUND; i++) // 遍历所有的格子
53 for (int j = 1; j <= WuLSJ.MAX_BOUND; j++) {
54 //Iterator<WuLDZ> it = this._WuL[i][j].iterator();
55 Iterator<WuLDZ> it = this._WuL.get(i).get(j).iterator();
56 while (it.hasNext()) { // 遍历一个格子
57 WuLDZ wldz = it.next();
58 wldz.nextPlace(); // 武林弟子走到下一个位置
59 //wlfz[wldz.get_row()][wldz.get_col()].add(wldz); // 在对应位置加入此武林弟子的引用
60 wlfz.get(wldz.get_row()).get(wldz.get_col()).add(wldz);
61 } // while
62 } // for
63
64 this._WuL = wlfz; // 更新武林方阵
65 }
66
67 public MyResult calcStat() { // 返回武林状态
68 MyResult result = new MyResult(0, 0, 0, 0, 0, 0); // 创建一个空结果
69
70 for (int i = 1; i <= WuLSJ.MAX_BOUND; i++) // 遍历所有的格子
71 for (int j = 1; j <= WuLSJ.MAX_BOUND; j++) {
72 //Iterator<WuLDZ> it = this._WuL[i][j].iterator();
73 Iterator<WuLDZ> it = this._WuL.get(i).get(j).iterator();
74 while (it.hasNext()) { // 遍历一个格子
75 WuLDZ wldz = it.next();
76 switch (wldz.get_symbol()) {
77 case 'S': // 少林
78 result.incShaoLDZ(wldz.get_ShengML());
79 break;
80 case 'W': // 武当
81 result.incWuDDZ(wldz.get_ShengML());
82 break;
83 case 'E': // 峨嵋
84 result.incEMDZ(wldz.get_ShengML());
85 break;
86 default:
87 } // switch
88
89 } // while
90 } // for
91
92 return result;
93 }
94
95 // Java 不支持泛型数组
96 private List<List<List<WuLDZ>>> createWLFZ() {
97 //List<WuLDZ>[][] wlfz = new ArrayList[WuLSJ.MAX_BOUND+1][WuLSJ.MAX_BOUND+1]; // 先创建武林方阵,注意Java没有泛型数组
98 List<List<List<WuLDZ>>> wlfz = new ArrayList<List<List<WuLDZ>>>(WuLSJ.MAX_BOUND+1); // 创建行
99 for (int i = 0; i <= WuLSJ.MAX_BOUND; i++) // 创建列
100 wlfz.add(new ArrayList<List<WuLDZ>>(WuLSJ.MAX_BOUND+1));
101
102 for (int i = 0; i <= WuLSJ.MAX_BOUND; i++) // 然后实例化方阵中的每个格子
103 for (int j = 0; j <= WuLSJ.MAX_BOUND; j++)
104 wlfz.get(i).add(new ArrayList<WuLDZ>());
105
106 return wlfz;
107 }
108 /**
109 * @param wuL
110 */
111 public WuLSJ() { // 构造函数
112 this._WuL = this.createWLFZ();
113 }
114
115 }
 
Main.java(主程序):
1 import java.util.Scanner;
2
3 //
4 //
5 // Generated by StarUML(tm) Java Add-In
6 //
7 // @ Project : HDU1107_WuLin
8 // @ File Name : Main.java
9 // @ Date : 2011-3-16
10 // @ Author : Nysanier
11 //
12 //
13
14
15
16
17 public class Main { // 模拟武林战斗
18 public static void main(String[] args) {
19 // 打开文件,读入测试组数
20 Scanner stdin = new Scanner(System.in);
21 int numOfCases = stdin.nextInt(); // 测试数据组数
22
23 for (int i = 0; i < numOfCases; i++) {
24 // 1. 创建一个空的武林,武林弟子工厂
25 WuLSJ wl = new WuLSJ();
26 WuLDZFactory factory = WuLDZFactory.getInstance();
27 int N = stdin.nextInt();
28
29 // 2. 边读入数据,边在武林中创建弟子
30 while (true) {
31 String symbol = stdin.next();
32 if (symbol.equals("0"))
33 break;
34
35 int row = stdin.nextInt();
36 int col = stdin.nextInt();
37 int NeiL = stdin.nextInt();
38 int WuY = stdin.nextInt();
39 int ShengML = stdin.nextInt();
40
41 wl.addDiZ(factory.createWuLDZ(symbol.charAt(0), row, col, NeiL, WuY, ShengML)); // 加入武林弟子
42 } // while
43
44 // 3. 模拟 N 步的武林战斗
45 for (int j = 0; j < N; j++) {
46 wl.nextStat();
47 }
48
49 // 4. 统计武林状态
50 MyResult result = wl.calcStat();
51
52 // 5. 输出结果
53 System.out.println(result.get_numOfShaoL() + " " + result.get_sumOfShaoL()); // 少林
54 System.out.println(result.get_numOfWuD() + " " + result.get_sumOfWuD()); // 少林
55 System.out.println(result.get_numOfEM() + " " + result.get_sumOfEM()); // 少林
56 System.out.println("***");
57 } // for
58 }
59 }
 
WuLDZFactory.java(武林弟子工厂):
1 //
2 //
3 // Generated by StarUML(tm) Java Add-In
4 //
5 // @ Project : HDU1107_WuLin
6 // @ File Name : WuLDZFactory.java
7 // @ Date : 2011-3-16
8 // @ Author : Nysanier
9 //
10 //
11
12
13
14
15 class WuLDZFactory { // 武林弟子工厂,单例模式实现
16 private static WuLDZFactory _instance; // 静态私有实例
17 private WuLDZFactory() { // 私有构造
18
19 }
20
21 public static WuLDZFactory getInstance() { // 静态返回单例
22 if (_instance == null) // 如果单例还没有构造
23 _instance = new WuLDZFactory(); // 那么先构造单例
24 return _instance; // 返回单例
25 }
26
27 public WuLDZ createWuLDZ(char sl, int rw, int cl, int NL, int WY, int SML) { // 创建武林弟子,工厂模式实现
28 switch (sl) { // 根据弟子代号
29 case 'S': // 少林弟子
30 return new ShaoLDZ(sl, rw, cl, NL, WY, SML);
31 case 'W': // 武当弟子
32 return new WuDDZ(sl, rw, cl, NL, WY, SML);
33 case 'E': // 峨嵋弟子
34 return new EMDZ(sl, rw, cl, NL, WY, SML);
35 default:
36 return null;
37 }
38 }
39 }
 
MyResult.java(结果):
1 //
2 //
3 // Generated by StarUML(tm) Java Add-In
4 //
5 // @ Project : HDU1107_WuLin
6 // @ File Name : MyResult.java
7 // @ Date : 2011-3-16
8 // @ Author : Nysanier
9 //
10 //
11
12 class MyResult { // 武林结果
13 private int _numOfShaoL;
14 private int _sumOfShaoL;
15 private int _numOfWuD;
16 private int _sumOfWuD;
17 private int _numOfEM;
18 private int _sumOfEM;
19
20 public void incShaoLDZ(int SML) { // 加入一个少林弟子
21 this._numOfShaoL ++;
22 this._sumOfShaoL += SML;
23 }
24
25 public void incWuDDZ(int SML) { // 加入一个武当弟子
26 this._numOfWuD ++;
27 this._sumOfWuD += SML;
28 }
29
30 public void incEMDZ(int SML) { // 加入一个峨嵋弟子
31 this._numOfEM ++;
32 this._sumOfEM += SML;
33 }
34
35 /**
36 * @param numOfShaoL
37 * @param sumOfShaoL
38 * @param numOfWuD
39 * @param sumOfWuD
40 * @param numOfEM
41 * @param sumOfEM
42 */
43 public MyResult(int numOfShaoL, int sumOfShaoL, int numOfWuD, int sumOfWuD,
44 int numOfEM, int sumOfEM) { // 构造函数
45 _numOfShaoL = numOfShaoL;
46 _sumOfShaoL = sumOfShaoL;
47 _numOfWuD = numOfWuD;
48 _sumOfWuD = sumOfWuD;
49 _numOfEM = numOfEM;
50 _sumOfEM = sumOfEM;
51 }
52
53 // Getter and Setter
54 public int get_numOfShaoL() {
55 return _numOfShaoL;
56 }
57
58 public void set_numOfShaoL(int numOfShaoL) {
59 _numOfShaoL = numOfShaoL;
60 }
61
62 public int get_sumOfShaoL() {
63 return _sumOfShaoL;
64 }
65
66 public void set_sumOfShaoL(int sumOfShaoL) {
67 _sumOfShaoL = sumOfShaoL;
68 }
69
70 public int get_numOfWuD() {
71 return _numOfWuD;
72 }
73
74 public void set_numOfWuD(int numOfWuD) {
75 _numOfWuD = numOfWuD;
76 }
77
78 public int get_sumOfWuD() {
79 return _sumOfWuD;
80 }
81
82 public void set_sumOfWuD(int sumOfWuD) {
83 _sumOfWuD = sumOfWuD;
84 }
85
86 public int get_numOfEM() {
87 return _numOfEM;
88 }
89
90 public void set_numOfEM(int numOfEM) {
91 _numOfEM = numOfEM;
92 }
93
94 public int get_sumOfEM() {
95 return _sumOfEM;
96 }
97
98 public void set_sumOfEM(int sumOfEM) {
99 _sumOfEM = sumOfEM;
100 }
101
102 }
 
WuLDZ.java(抽象武林弟子):
1 //
2 //
3 // Generated by StarUML(tm) Java Add-In
4 //
5 // @ Project : HDU1107_WuLin
6 // @ File Name : WuLDZ.java
7 // @ Date : 2011-3-16
8 // @ Author : Nysanier
9 //
10 //
11
12 /** 由武林弟子工厂(WuLDZFactory)构造武林弟子(WuLDZ) */
13 abstract class WuLDZ {
14 protected char _symbol; // 弟子代号
15 protected int _row; // 行号
16 protected int _col; // 列号
17 protected int _NeiL; // 内力
18 protected int _WuY; // 武艺
19 protected int _ShengML; // 生命力
20 protected boolean _currentDirection; // 当前方向,初始为正向,即初始的方向
21
22 public abstract void nextPlace(); // 下一个位置
23
24 public abstract int getGongJL(); // 得到当前攻击力,与战前生命力有关,需实时计算
25
26 public int beAttacked(int GongJL) { // 被攻击,返回剩余的生命力
27 this._ShengML -= GongJL;
28 return this._ShengML;
29 }
30
31 /**
32 * @param symbol
33 * @param row
34 * @param col
35 * @param neiL
36 * @param wuY
37 * @param shengML
38 */
39 public WuLDZ(char symbol, int row, int col, int neiL, int wuY, int shengML) {
40 _symbol = symbol;
41 _row = row;
42 _col = col;
43 _NeiL = neiL;
44 _WuY = wuY;
45 _ShengML = shengML;
46
47 this._currentDirection = true; // 初始为正向
48 }
49
50 // Getter and Setter
51 public char get_symbol() {
52 return _symbol;
53 }
54
55 public void set_symbol(char symbol) {
56 _symbol = symbol;
57 }
58
59 public int get_row() {
60 return _row;
61 }
62
63 public void set_row(int row) {
64 _row = row;
65 }
66
67 public int get_col() {
68 return _col;
69 }
70
71 public void set_col(int col) {
72 _col = col;
73 }
74
75 public int get_NeiL() {
76 return _NeiL;
77 }
78
79 public void set_NeiL(int neiL) {
80 _NeiL = neiL;
81 }
82
83 public int get_WuY() {
84 return _WuY;
85 }
86
87 public void set_WuY(int wuY) {
88 _WuY = wuY;
89 }
90
91 public int get_ShengML() {
92 return _ShengML;
93 }
94
95 public void set_ShengML(int shengML) {
96 _ShengML = shengML;
97 }
98
99 public boolean is_currentDirection() {
100 return _currentDirection;
101 }
102
103 public void set_currentDirection(boolean currentDirection) {
104 _currentDirection = currentDirection;
105 }
106
107 }
 
ShaoLDZ.java(少林弟子):
1 //
2 //
3 // Generated by StarUML(tm) Java Add-In
4 //
5 // @ Project : HDU1107_WuLin
6 // @ File Name : ShaoLDZ.java
7 // @ Date : 2011-3-16
8 // @ Author : Nysanier
9 //
10 //
11
12
13
14
15 class ShaoLDZ extends WuLDZ { // 少林弟子
16 public void nextPlace() { // 上下移动,先下
17 if (this._currentDirection == true) { // 如果当前是正向
18 if (this._row == WuLSJ.MAX_BOUND) { // 且到达最大边界
19 this._currentDirection = false; // 那么调换方向
20 this._row -= 1; // 并向前走一步
21 }
22 else { // 但没有到达最大边界
23 this._row += 1; // 那么直接向前走一步
24 }
25 }
26 else { // 如果当前是反向
27 if (this._row == WuLSJ.MIN_BOUND) { // 且到达最小边界
28 this._currentDirection = true; // 那么调换方向
29 this._row += 1; // 并向前走一步
30 }
31 else { // 但没有到达最小边界
32 this._row -= 1; // 那么直接向前走一步
33 }
34 }
35 }
36
37 @Override
38 public int getGongJL() { // 计算当前攻击力
39 // TODO Auto-generated method stub
40
41 return (int) ((0.5 * this._NeiL + 0.5 * this._WuY) * (this._ShengML + 10) / 100); // 少林派攻击力 = (0.5 * 内力 + 0.5 * 武艺) * (战前生命力 + 10) / 100
42 }
43
44 /**
45 * @param symbol
46 * @param row
47 * @param col
48 * @param neiL
49 * @param wuY
50 * @param shengML
51 */
52 public ShaoLDZ(char symbol, int row, int col, int neiL, int wuY, int shengML) { // 构造函数
53 super(symbol, row, col, neiL, wuY, shengML);
54 // TODO Auto-generated constructor stub
55 }
56
57 }
 
WuDDZ.java(武当弟子):
1 //
2 //
3 // Generated by StarUML(tm) Java Add-In
4 //
5 // @ Project : HDU1107_WuLin
6 // @ File Name : WuDDZ.java
7 // @ Date : 2011-3-16
8 // @ Author : Nysanier
9 //
10 //
11
12
13
14
15 class WuDDZ extends WuLDZ { // 武当弟子
16 public void nextPlace() { // 左右移动,先右
17 if (this._currentDirection == true) { // 如果当前是正向
18 if (this._col == WuLSJ.MAX_BOUND) { // 且到达最大边界
19 this._currentDirection = false; // 那么调换方向
20 this._col -= 1; // 并向前走一步
21 }
22 else { // 但没有到达最大边界
23 this._col += 1; // 那么直接向前走一步
24 }
25 }
26 else { // 如果当前是反向
27 if (this._col == WuLSJ.MIN_BOUND) { // 且到达最小边界
28 this._currentDirection = true; // 那么调换方向
29 this._col += 1; // 并向前走一步
30 }
31 else { // 但没有到达最小边界
32 this._col -= 1; // 那么直接向前走一步
33 }
34 }
35 }
36
37 @Override
38 public int getGongJL() { // 计算当前攻击力
39 // TODO Auto-generated method stub
40
41 return (int) ((0.8 * this._NeiL + 0.2 * this._WuY) * (this._ShengML + 10) / 100); // 武当派攻击力 = (0.8 * 内力 + 0.2 * 武艺) * (战前生命力 + 10) / 100
42 }
43
44 /**
45 * @param symbol
46 * @param row
47 * @param col
48 * @param neiL
49 * @param wuY
50 * @param shengML
51 */
52 public WuDDZ(char symbol, int row, int col, int neiL, int wuY, int shengML) { // 构造函数
53 super(symbol, row, col, neiL, wuY, shengML);
54 // TODO Auto-generated constructor stub
55 }
56 }
 
EMDZ.java(峨嵋弟子):
1 //
2 //
3 // Generated by StarUML(tm) Java Add-In
4 //
5 // @ Project : HDU1107_WuLin
6 // @ File Name : EMDZ.java
7 // @ Date : 2011-3-16
8 // @ Author : Nysanier
9 //
10 //
11
12
13
14
15 class EMDZ extends WuLDZ { // 峨嵋弟子
16 public void nextPlace() { // 右下-左上移动,先右下
17 // 特例,在(1,12)和(12,1)没法移动,保持原地
18 if ((this._row == WuLSJ.MIN_BOUND && this._col == WuLSJ.MAX_BOUND)
19 || (this._row == WuLSJ.MAX_BOUND && this._col == WuLSJ.MIN_BOUND))
20 return;
21
22 // 一般情况
23 if (this._currentDirection == true) { // 如果当前是正向
24 if (this._row == WuLSJ.MAX_BOUND || this._col == WuLSJ.MAX_BOUND) { // 且到达最大边界
25 this._currentDirection = false; // 那么调换方向
26 this._row -= 1; // 并向前走一步
27 this._col -= 1;
28 }
29 else { // 但没有到达最大边界
30 this._row += 1; // 那么直接向前走一步
31 this._col += 1;
32 }
33 }
34 else { // 如果当前是反向
35 if (this._row == WuLSJ.MIN_BOUND || this._col == WuLSJ.MIN_BOUND) { // 且到达最小边界
36 this._currentDirection = true; // 那么调换方向
37 this._row += 1; // 并向前走一步
38 this._col += 1;
39 }
40 else { // 但没有到达最小边界
41 this._row -= 1; // 那么直接向前走一步
42 this._col -= 1;
43 }
44 }
45
46 }
47
48 @Override
49 public int getGongJL() {
50 // TODO Auto-generated method stub
51
52 return (int) ((0.2 * this._NeiL + 0.8 * this._WuY) * (this._ShengML + 10) / 100); // 峨嵋派攻击力 = (0.2 * 内力 + 0.8 * 武艺) * (战前生命力 + 10) / 100
53 }
54
55 /**
56 * @param symbol
57 * @param row
58 * @param col
59 * @param neiL
60 * @param wuY
61 * @param shengML
62 */
63 public EMDZ(char symbol, int row, int col, int neiL, int wuY, int shengML) { // 构造函数
64 super(symbol, row, col, neiL, wuY, shengML);
65 // TODO Auto-generated constructor stub
66 }
67
68 }
 
总结:
面向对象结合OOADP设计模式简化了问题(虽然增加了代码行数),使一个复杂的问题变得解决,并且具有较好的可维护性,可扩展性,以及可靠性。
posted @ 2011-03-16 20:15  F.N.  阅读(1398)  评论(0编辑  收藏  举报