POJ 1414 Life Line (DP & DFS)

原题链接。大意: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: }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
POJ 1321 排兵布阵问题可以使用 DFS 算法求解。 题目要求在一个 n x n 的棋盘上,放置 k 个棋子,其中每行、每列都最多只能有一个棋子。我们可以使用 DFS 枚举每个棋子的位置,对于每个棋子,尝试将其放置在每一行中未被占用的位置上,直到放置了 k 个棋子。在 DFS 的过程中,需要记录每行和每列是否已经有棋子,以便在尝试放置下一个棋子时进行判断。 以下是基本的 DFS 模板代码: ```python def dfs(row, cnt): global ans if cnt == k: ans += 1 return for i in range(row, n): for j in range(n): if row_used[i] or col_used[j] or board[i][j] == '.': continue row_used[i] = col_used[j] = True dfs(i + 1, cnt + 1) row_used[i] = col_used[j] = False n, k = map(int, input().split()) board = [input() for _ in range(n)] row_used = [False] * n col_used = [False] * n ans = 0 dfs(0, 0) print(ans) ``` 其中,row 代表当前尝试放置棋子的行数,cnt 代表已经放置的棋子数量。row_used 和 col_used 分别表示每行和每列是否已经有棋子,board 则表示棋盘的状态。在尝试放置棋子时,需要排除掉无法放置的位置,即已经有棋子的行和列,以及棋盘上标记为 '.' 的位置。当放置了 k 个棋子时,即可计数一次方案数。注意,在回溯时需要将之前标记为已使用的行和列重新标记为未使用。 需要注意的是,在 Python 中,递归深度的默认限制为 1000,可能无法通过本题。可以通过以下代码来解除限制: ```python import sys sys.setrecursionlimit(100000) ``` 完整代码如下:

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值