[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
****************************************************************/




目录
相关文章
|
6月前
|
算法 Java C语言
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-8 算法训练 操作格子 线段树
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-8 算法训练 操作格子 线段树
56 0
|
6月前
|
算法 Java C语言
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-5 算法训练 最短路
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-5 算法训练 最短路
40 0
|
6月前
|
算法 Java C语言
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-1 算法训练 区间k大数查询
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-1 算法训练 区间k大数查询
39 0
|
6月前
|
人工智能 算法 Java
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-7 算法训练 逆序对 平衡二叉树
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-7 算法训练 逆序对 平衡二叉树
56 0
|
4月前
|
存储 定位技术
【天梯赛】L2-048 寻宝图 (DFS做法)
遇到一个非'0'字符(也就是'1'和 宝藏'2'到'9')就让ans++,同时将这个非'0'字符染色为'0',然后往四个方向(上、下、左、右)搜索,这里的目的是那一片岛屿(也就是那一片为'1'的部分)都染色为‘0’。本题就请你统计一下,给定的地图上一共有多少岛屿,其中有多少是有宝藏的岛屿。为了判断有宝藏的岛屿,这里我开了一个全局变量f来判断这一片岛屿是否有宝藏(也就是有无字符'2'-'9'),当搜到字符'2'~'9'时就将f标记为1。在一行中输出 2 个整数,分别是岛屿的总数量和有宝藏的岛屿的数量。
84 5
|
6月前
|
C语言
青蛙跳台阶:我如何得知它是一道斐波那契数列题?——应用题破题“三板斧”(一)
这篇内容介绍了C语言学习中的经典例题——斐波那契数列,强调了解题思路的重要性。斐波那契数列是一个数列,其中每个数是前两个数的和。文章指出,很多类似题目,如“青蛙跳台阶”,实质上都在考察斐波那契数列的实现。文中提供了斐波那契数列的定义、代码实现和递归与非递归的思路,并鼓励读者从问题中分析出解题模型,而非直接套用已知方法。此外,还提及了一道相关题目“矩形覆盖问题”,以供进一步练习。
49 0
|
6月前
|
机器学习/深度学习 算法 测试技术
青蛙跳台阶:我如何得知它是一道斐波那契数列题?——应用题破题“三板斧”(二)
这篇内容是关于解题策略的,主要介绍了在面对应用题时可以采用的“三板斧”方法:举例、模拟和找规律。通过一个走楼梯的例子详细解释了这三个步骤如何运用。首先,举例将抽象问题具体化,比如走5级台阶有几种方式。其次,通过模拟不同情况,例如思考走每一步的可能,发现递归或循环的模式。最后,通过找规律归纳出一般性的解决方案,这里发现走台阶问题与斐波那契数列相关。文章还提到了一个拓展案例——矩形覆盖问题,同样可以用类似的方法分析。总的来说,文章强调了解题过程中理解和转化问题的重要性,以及通过训练提升这方面能力。
56 0
|
6月前
日拱一卒,月进一步(6)(杨辉三角2)
119. 杨辉三角 II - 力扣(LeetCode)
42 0
|
6月前
|
Java C语言 C++
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-150 6-1 递归求二项式系数值
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-150 6-1 递归求二项式系数值
65 1
|
6月前
|
算法 Java C语言
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-568 孪生素数对
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-568 孪生素数对
39 0
下一篇
无影云桌面