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: }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值