链接: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

输入描述:
第一行为白子需要走的步数

接下来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[][];
int dir[][]={-,,,,,-,,,-,-,-,,,-,,};//上,下,左,右,左上,右上,左下,右下
int n,ans; int find_sum(int x,int y,int dx,int dy,int nwcolor,int others)
{
int cnt=;
x+=dx; y+=dy;
while(x>=&&x<&&y>=&&y<)
{
if(mp[x][y]==nwcolor)
return cnt;
if(mp[x][y]!=others)
return ;
x+=dx;
y+=dy;
cnt++;
}
return ;
}
void dfs(int step)
{
if(step==n)
{
int cnt=;
for(int i=; i<; i++)
{
for(int j=; j<; j++)
if(mp[i][j]==) cnt++;
}
ans=max(ans,cnt);
return;
}
int nw,lst;
vector<p> g;//保存要改变的棋子位置
if(step%==)
{
nw=;
lst=;
}
else
{
nw=;
lst=;
}
for(int i=; i<; i++)
{
for(int j=; j<; j++)
{
if(mp[i][j]==)
{
int flag=;//回溯标记
for(int k=; k<; k++)
{
int cnt=find_sum(i,j,dir[k][],dir[k][],nw,lst);//从当前位置[i,j]沿当前方向可以改变多少个棋子
if(cnt>)
{
int x=i,y=j;
for(int ii=; ii<cnt; ii++)
{
mp[x][y]=nw;
g.push_back(make_pair(x,y));//保存要更新的棋子位置
x+=dir[k][];
y+=dir[k][];
}
flag=;
}
}
if(flag)
{
dfs(step+);
for(int ii=; ii<g.size(); ii++)//回溯
{
mp[g[ii].first][g[ii].second]=lst;
}
mp[i][j]=;
g.clear();
}
}
}
}
} int main()
{
scanf("%d",&n);
n=*n-;
for(int i=; i<; i++)
{
for(int j=; j<; j++)
{
scanf("%d",&mp[i][j]);
}
}
ans=;
dfs();
printf("%d\n",ans);
return ;
}

2019 深信服 下棋(DFS+回溯)的更多相关文章

  1. 【面试总结】2019校招京东一面二面,及深信服技术面(已拿深信服offer),还有百度一面

    百度一面: 1.自我介绍+项目介绍 2.进程和线程的区别 3.常用linux命令列举 4.堆排序 5.快速排序 反问环节. 现在的状态是岗位转推,毕竟百度投的是开发岗. 京东一面: 1.C++三大特性 ...

  2. 蓝桥杯 算法提高 8皇后·改 -- DFS 回溯

      算法提高 8皇后·改   时间限制:1.0s   内存限制:256.0MB      问题描述 规则同8皇后问题,但是棋盘上每格都有一个数字,要求八皇后所在格子数字之和最大. 输入格式 一个8*8 ...

  3. 素数环(dfs+回溯)

    题目描述: 输入正整数n,把整数1,2...n组成一个环,使得相邻两个数和为素数.输出时从整数1开始逆时针排列并且不能重复: 例样输入: 6 例样输出: 1 4 3 2 5 6 1 6 5 2 3 4 ...

  4. NOJ 1074 Hey Judge(DFS回溯)

    Problem 1074: Hey Judge Time Limits:  1000 MS   Memory Limits:  65536 KB 64-bit interger IO format: ...

  5. HDU 1016 Prime Ring Problem(经典DFS+回溯)

    Prime Ring Problem Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

  6. HDU 2181 哈密顿绕行世界问题(经典DFS+回溯)

    哈密顿绕行世界问题 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  7. HDU1016 Prime Ring Problem(DFS回溯)

    Prime Ring Problem Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

  8. uva 193 Graph Coloring(图染色 dfs回溯)

    Description You are to write a program that tries to find an optimal coloring for a given graph. Col ...

  9. 深信服模式(先做减法,必须拜访客户三次、研究需求方向,把产品的问题控制住,快速反应,在未来十年,绝大部分业务都会搬到Internet上来,实现All on Internet)good

    深圳市盛凯信息科技有限公司与深信服合作多年,可以说是看着深信服“飞速”长大的.盛凯的总经理邓渊在采访中笑言:“他们(深信服)发展得太快,而我们发展得太慢.” 深信服的产品线已从最初只有VPN一条,到目 ...

随机推荐

  1. Vacation

    题目看上去倒是蛮复杂的样子嘞!

  2. LINUX 怎么实现root和普通用户的切换及怎么更改root密码

    在linux系统中执行什么命令后可以使$变为#?     先说下$和#在linux系统终端(命令行)中通常代表的什么:$打头的表示这不是在root用户(管理员用户)下执行的命令#打头的和前者相反,即r ...

  3. memcache安装 基于Red Hat 7.4

    Linux版本为 Red Hat 7.4 一.安装 1.下载:http://memcached.org/downloads 解压: tar -xzvf memcached-1.5.3.tar.gz 得 ...

  4. eclipse 自定义代码块设置(代码模板)

    eclipse设置自定义代码模板 window -> show View -> other -> Templates 原来main模板 修改模板 再次插入

  5. Hybrid App 开发快速指南

    链接:https://blog.csdn.net/valada/article/details/81639658

  6. layui-表格宽度自适应

    不设置表格宽度,表格默认全屏 可以通过以下方式设置表格宽度

  7. 【C语言】赋值运算中的类型转换

    #include<stdio.h> int main() { int a, b; double x = 1.54; char ch; a = x; x = ; b = 'a'; ch = ...

  8. laravel qq邮件配置

  9. Plastic Bottle Manufacturer - Consumer Demand For Plastic Bottles Becomes Higher

    Since transparent containers enable consumers to clearly see the contents, consumers are increasingl ...

  10. char **argv 与char *argv[]

    1.char **argv 分析:argv是一个指针变量,argv的指向(*argv)是char *,也就是argv指向的也是一个指针 : *argv的指向(**argv)是char. 2.char ...