原题链接。大意:1~9个玩家,很多块石头,一个等边三角形构成一张网状的图。每个顶点的数字代表玩家编号,0为空,求轮到玩家C时候可以的最大得分。其中分数的计算规则如下:
玩家可以把自己的编号放在标号为0的顶点处(很多个编号为0的顶点,任意其一,假设为M点),从而使图中所有顶点分成很多组,每一组是相邻并且数字相同的顶点构成,之后可以去掉不与0相邻的组。去掉一个非玩家自己编号的顶点+1分,去掉玩家本身编号顶点-1分。之后就是玩家放置在这个M顶点处的最终得分。
我的思路:图的规模不是很大,邻接矩阵存储,枚举每一个0顶点 –> 扫描图标记可以去掉的顶点 –> 从0顶点周围DFS,即与0相邻的组不能被去掉 –> 计算去掉的非玩家本身顶点数和玩家本身顶点数之差。代码如下:
1: #include <iostream>
2: #include <memory.h>
3: using namespace std;
4: const int board_size = 12;
5: const int min_int = -(1<<15);
6: const int max_int = (1<<15);
7:
8: int board[board_size][board_size];
9: bool isRemove[board_size][board_size];
10:
11: bool canRemove(int i, int j)
12: {
13: if (board[i-1][j-1] && board[i-1][j] && board[i][j-1]
14: && board[i][j+1] && board[i+1][j] && board[i+1][j+1])
15: return true;
16: return false;
17: }
18:
19: void dfs(const int row, const int col)
20: {
21: int i=row, j=col;
22: if (isRemove[i-1][j-1] && board[i-1][j-1]==board[i][j])
23: {
24: isRemove[i-1][j-1] = false;
25: dfs(i-1, j-1);
26: }
27: if (isRemove[i-1][j] && board[i-1][j]==board[i][j])
28: {
29: isRemove[i-1][j] = false;
30: dfs(i-1,j);
31: }
32: if (isRemove[i][j-1] && board[i][j-1]==board[i][j])
33: {
34: isRemove[i][j-1] = false;
35: dfs(i, j-1);
36: }
37: if (isRemove[i][j+1] && board[i][j+1]==board[i][j])
38: {
39: isRemove[i][j+1] = false;
40: dfs(i, j+1);
41: }
42: if (isRemove[i+1][j] && board[i+1][j]==board[i][j])
43: {
44: isRemove[i+1][j] = false;
45: dfs(i+1, j);
46: }
47: if (isRemove[i+1][j+1] && board[i+1][j+1]==board[i][j])
48: {
49: isRemove[i+1][j+1] = false;
50: dfs(i+1, j+1);
51: }
52: }
53:
54: int getOnePoint(const int boardNum, const int currPlayer)
55: {
56: memset(isRemove, false, sizeof(isRemove));
57: for (int i=1; i<=boardNum; i++)
58: {
59: for (int j=1; j<=i; j++)
60: {
61: if (board[i][j]>0 && canRemove(i, j))
62: isRemove[i][j] = true;
63: }
64: }
65: for (int i=1; i<=boardNum; i++)
66: {
67: for (int j=1; j<=i; j++)
68: {
69: if (board[i][j]==0)
70: {
71: dfs(i-1, j-1);
72: dfs(i-1,j);
73: dfs(i, j-1);
74: dfs(i, j+1);
75: dfs(i+1, j);
76: dfs(i+1, j+1);
77: }
78: }
79: }
80: int otherGroup=0, myGroup=0;
81: for (int i=1; i<=boardNum; i++)
82: {
83: for (int j=1; j<=i; j++)
84: {
85: if (isRemove[i][j] && board[i][j]==currPlayer)
86: myGroup++;
87: if (isRemove[i][j] && board[i][j]!=currPlayer)
88: otherGroup++;
89: }
90: }
91: return otherGroup-myGroup;
92: }
93:
94: int getPoint(const int boardNum, const int currPlayer)
95: {
96: int maxRes=min_int;
97: for (int i=1; i<=boardNum; i++)
98: {
99: for (int j=1; j<=i; j++)
100: {
101: if (board[i][j]==0)
102: {
103: board[i][j] = currPlayer;
104: int temp = getOnePoint(boardNum, currPlayer);
105: if (maxRes<temp)
106: maxRes = temp;
107: board[i][j] = 0;
108: }
109: }
110: }
111: return maxRes;
112: }
113:
114: int main()
115: {
116: int boardNum=0, currPlayer=0;
117: while (cin >> boardNum >> currPlayer && boardNum!=0 && currPlayer!=0)
118: {
119: memset(board, 0, sizeof(board));
120: board[0][0] = board[0][1] = board[0][2] = max_int;
121: for (int i=1; i<=boardNum; i++)
122: {
123: board[i][0] = max_int;
124: board[i][i+1] = max_int;
125: for (int j=1; j<=i; j++)
126: cin >> board[i][j];
127: }
128: for (int j=0; j<=boardNum+1; j++)
129: board[boardNum+1][j] = max_int;
130:
131: int maxRes = getPoint(boardNum, currPlayer);
132: cout << maxRes << endl;
133: }
134: return 0;
135: }