鏈接:https://www.nowcoder.com/questionTerminal/a0feb0696e2043a5b3b0779fa861b64a?f=discussion
來源:牛客網
8x8的棋盤上,布有黑白兩色棋子,白子先下,當白子下N手后,棋盤上最多有可能留下多少顆白子?
下法規則:
1.每次落子后,以該棋子為中心的8個方向(米字形的8條直線),如果有同色棋子,
且兩個同色棋子之間連續排列着若干個異色棋子,無空白及同色棋子。則,這次落子可以把這些夾在中間的異色棋子全部翻色(即黑變白,白變黑)。
2. 黑白子交錯落子。
3. 如果一個位置上有棋子,不能繼續在該位置上落子;
4. 如果一個位置上落子后,不能翻對手的棋子,則該位置不能落子;
1表示黑色,2表示白色,0表示空白未落子
白棋落子后,棋盤變化情況如下所示:
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 1 2 0 0 0 => 0 0 0 1 2 0 0 0
0 0 0 2 1 0 0 0 0 0 0 2 2 2 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 1 2 0 0 0 => 0 0 0 1 2 0 0 0
0 0 1 2 1 2 0 0 0 0 1 2 1 1 1 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
下法規則:
1.每次落子后,以該棋子為中心的8個方向(米字形的8條直線),如果有同色棋子,
且兩個同色棋子之間連續排列着若干個異色棋子,無空白及同色棋子。則,這次落子可以把這些夾在中間的異色棋子全部翻色(即黑變白,白變黑)。
2. 黑白子交錯落子。
3. 如果一個位置上有棋子,不能繼續在該位置上落子;
4. 如果一個位置上落子后,不能翻對手的棋子,則該位置不能落子;
1表示黑色,2表示白色,0表示空白未落子
白棋落子后,棋盤變化情況如下所示:
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 1 2 0 0 0 => 0 0 0 1 2 0 0 0
0 0 0 2 1 0 0 0 0 0 0 2 2 2 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 1 2 0 0 0 => 0 0 0 1 2 0 0 0
0 0 1 2 1 2 0 0 0 0 1 2 1 1 1 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
輸入描述:
第一行為白子需要走的步數
接下來8行數據,指明棋盤上的棋子狀態,其中1為黑子,2為白子,0為空位置
輸出描述:
白子下完N手后,棋盤上的白子個數的最大可能。
示例1
輸入
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 0 0 0 0 0 0 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
輸出
4
#include <iostream> #include <algorithm> #include <cstring> #include <cstdio> #include <vector> #include <cmath> #define ll long long using namespace std; typedef pair<int,int> p; int mp[8][8]; int dir[8][2]={-1,0,1,0,0,-1,0,1,-1,-1,-1,1,1,-1,1,1};//上,下,左,右,左上,右上,左下,右下 int n,ans; int find_sum(int x,int y,int dx,int dy,int nwcolor,int others) { int cnt=1; x+=dx; y+=dy; while(x>=0&&x<8&&y>=0&&y<8) { if(mp[x][y]==nwcolor) return cnt; if(mp[x][y]!=others) return 0; x+=dx; y+=dy; cnt++; } return 0; } void dfs(int step) { if(step==n) { int cnt=0; for(int i=0; i<8; i++) { for(int j=0; j<8; j++) if(mp[i][j]==2) cnt++; } ans=max(ans,cnt); return; } int nw,lst; vector<p> g;//保存要改變的棋子位置 if(step%2==0) { nw=2; lst=1; } else { nw=1; lst=2; } for(int i=0; i<8; i++) { for(int j=0; j<8; j++) { if(mp[i][j]==0) { int flag=0;//回溯標記 for(int k=0; k<8; k++) { int cnt=find_sum(i,j,dir[k][0],dir[k][1],nw,lst);//從當前位置[i,j]沿當前方向可以改變多少個棋子 if(cnt>1) { int x=i,y=j; for(int ii=0; ii<cnt; ii++) { mp[x][y]=nw; g.push_back(make_pair(x,y));//保存要更新的棋子位置 x+=dir[k][0]; y+=dir[k][1]; } flag=1; } } if(flag) { dfs(step+1); for(int ii=0; ii<g.size(); ii++)//回溯 { mp[g[ii].first][g[ii].second]=lst; } mp[i][j]=0; g.clear(); } } } } } int main() { scanf("%d",&n); n=2*n-1; for(int i=0; i<8; i++) { for(int j=0; j<8; j++) { scanf("%d",&mp[i][j]); } } ans=0; dfs(0); printf("%d\n",ans); return 0; }