[Nowcoder] 2021年度训练联盟热身训练赛第六场 Mini Battleship | 深搜 回溯 乱搞

简介: 题意:给定一个n ∗ n n * nn∗n的矩阵,其中在X XX上一定不可以放置船,而在O OO上面一定要放置船,在′ . ′ '.' 上面可以放置船,也可以不放,问将以下m mm艘船,大小均为1 ∗ x 1 * x1∗x,放置在矩阵中的方案数量思路:类似经典的八皇后问题,首先将所有的m个都成功放置之后,并且所有的O均已成功放置船艘,此时的方案书就应该 + 1注意船的形状一共有两种情况:横着和竖着,但是对于1 * 1的情况来说就只有一种状态,这里要特判掉我们用j u d g e ( ) judge()judge()函数来判断是否能够是否可以放置该船,

题目链接


题目描述


Battleship is a game played by two players. Each player has their own grid  which is hidden from their opponent. Each player secretly places some ships on their grid. Each ship covers a horizontal or vertical straight line of one or more continguous squares. Ships cannot overlap. All ships are considered distinct, even if they have the same size.

After placing their ships, the players then take turns taking shots at their opponent’s ships by calling out a coordinate of their opponent’s grid. The opponent must honestly say whether the shot was a hit or a miss. When all of a ship’s squares are hit, that ship sinks (“You sunk my battleship!!”). A player loses when all of their ships are sunk.

Bob is playing a game of Mini Battleship against Alice. Regular Battleship is played on a 10×10 grid with 5 ships. Mini Battleship is much smaller, with a grid no larger than 5×5 and possibly fewer than 5 ships. Bob wonders how many ship placements are possible on Alice’s board given what he knows so far.

The answer will be 0 if Alice is cheating! (Or, if the game setup isn’t possible.)


输入


The first line of input contains two space-separated integers n (1 ≤ n ≤ 5) and k (1 ≤ k ≤ 5),which represent a game of Mini Battleship played on an n×n grid with k ships.

Each of the next n lines contains a string s (|s| = n). This is what Bob sees of Alice’s grid so far.

A character ‘X’ represents one of Bob’s shots that missed. A character ‘O’ (Letter O, not zero) represents one of Bob’s shots that hit. A Dot (‘.’) represents a square where Bob has not yet taken a shot. Each of the next k lines contains a single integer x (1 ≤ x ≤ n). These are the sizes of the ships.


输出


Output a single integer, which is the number of ways the k distinct ships could be placed on Alice’s grid and be consistent with what Bob sees.


样例输入 Copy


【样例1】

4 3
....
.OX.
....
O..X
3
2
1


【样例2】

4 4
.X.X
.XX.
...X
....
1
2
3
4


【样例3】

2 2
..
..
2
2


样例输出 Copy


【样例1】

132


【样例2】

6


【样例3】

4


题意:


给定一个n ∗ n n * nn∗n的矩阵,其中在X XX上一定不可以放置船,而在O OO上面一定要放置船,在′ . ′ '.' 上面可以放置船,也可以不放,问将以下m mm艘船,大小均为1 ∗ x 1 * x1∗x,放置在矩阵中的方案数量


思路:


类似经典的八皇后问题,

首先将所有的m个都成功放置之后,并且所有的O均已成功放置船艘,此时的方案书就应该 + 1

注意船的形状一共有两种情况:横着和竖着,但是对于1 * 1的情况来说就只有一种状态,这里要特判掉

我们用j u d g e ( ) judge()judge()函数来判断是否能够是否可以放置该船,如果说要是放置过程中遇到了’X’,那是一定不能够放下去的,反之可以放下这艘船,对于能够放下去的船,我们将它的位置vis[i][j] += 1;


char s[7][7];
int in[10];
int n, m;
int ans;
int vis[7][7];
bool ok() {
    for(int i = 1; i <= n; i++) {
        for(int j = 1; j <= n; j++) {
            if(s[i][j] == 'O' && vis[i][j] == 0)
                return false;/// O must place but not vis
        }
    }
    return true;
}
bool judge(int pos, int x, int y, int t) {
    if(t == 0) {
        if(y + in[pos] - 1 > n)
            return false;/// <= n
        for(int i = y; i < y + in[pos]; i++) {
            if(vis[x][i] || s[x][i] == 'X')
                return false;/// X not place
        }
    } else {
        if(x + in[pos] - 1 > n)
            return false;
        for(int i = x; i < x + in[pos]; i++) {
            if(vis[i][y] || s[i][y] == 'X')
                return false;
        }
    }
    return true;
}
void addBattleship(int x, int y, int pos, int id, int val) {
    if(id == 0) {
        for(int i = y; i < y + in[pos]; i++) {
            vis[x][i] += val;
        }
    } else {
        for(int i = x; i < x + in[pos]; i++) {
            vis[i][y] += val;
        }
    }
}
void dfs(int x) {
    if(x >= m + 1) {
        if(ok())
            ans ++;
        return ;
    }
    for(int i = 1; i <= n; i++) {
        for(int j = 1; j <= n; j++) {
            if(vis[i][j] || s[i][j] == 'X')
                continue;/// X must not place
            int lim = 1;
            if(in[x] == 1)
                lim = 0;
            for(int t = 0; t <= lim; t++) {
                if(judge(x, i, j, t)) {/// can place
                    addBattleship(i, j, x, t, 1);
                    dfs(x + 1);
                    addBattleship(i, j, x, t, -1);
                }
            }
        }
    }
}
int main() {
    cin >> n >> m;
    for(int i = 1; i <= n; i++)
        cin >> s[i] + 1;
    for(int i = 1; i <= m; i++)
        cin >> in[i];
    sort(in+1,in+1+m);
    ans = 0;
    dfs(1);
    cout << ans << endl;
    return 0;
}
/**
4 3
....
.OX.
....
O..X
3
2
1
**/
/**************************************************************
    Problem: 18783
    Language: C++
    Result: 正确
    Time:1908 ms
    Memory:2036 kb
****************************************************************/




目录
相关文章
|
3月前
|
算法 Java C语言
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-246 算法训练 猴子吃包子
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-246 算法训练 猴子吃包子
36 2
|
3月前
|
机器学习/深度学习 算法 Java
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-996 车的放置
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-996 车的放置
43 0
|
3月前
|
算法 Java C语言
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-8 算法训练 操作格子 线段树
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-8 算法训练 操作格子 线段树
29 0
|
1天前
日拱一卒,月进一步(6)(杨辉三角2)
119. 杨辉三角 II - 力扣(LeetCode)
|
3月前
|
算法 Java C语言
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-936 砝码称重
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-936 砝码称重
30 0
|
3月前
|
Java C语言 C++
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-380 绘制地图
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-380 绘制地图
27 0
|
3月前
|
Java C语言 C++
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-150 6-1 递归求二项式系数值
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-150 6-1 递归求二项式系数值
40 1
|
3月前
|
算法 Java C语言
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-481 阿尔法乘积
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-481 阿尔法乘积
24 0
|
5月前
|
图计算
【LeetCode 热题 HOT 100】42. 接雨水【困难】
【LeetCode 热题 HOT 100】42. 接雨水【困难】
|
6月前
|
算法 Java
代码随想录算法训练营第三十四天 | LeetCode 860. 柠檬水找零、406. 根据身高重建队列、452. 用最少数量的箭引爆气球
代码随想录算法训练营第三十四天 | LeetCode 860. 柠檬水找零、406. 根据身高重建队列、452. 用最少数量的箭引爆气球
39 0