【备战秋招】每日一题:2023.3.5-米哈游笔试-n皇后

为了更好的阅读体检,可以查看我的算法学习网
在线评测链接:P1064

题目内容

塔子哥是一个热衷于国际象棋的棋手,他最近在研究 n n n 皇后问题。在国际象棋中,皇后是一种强大的棋子,能够沿着横、竖、斜线攻击其他棋子。

而在 n n n 皇后问题中,皇后也是一种强大的棋子,它能攻击同一行、同一列以及同一 45 45 45 度角斜线和 135 135 135 度角斜线上的其他皇后。

塔子哥手上拿着一个 n × n n\times n n×n 的棋盘,上面已经放置了一些皇后。他希望再放置一个皇后,使得所有的皇后不会互相攻击。

对于一个 n × n n\times n n×n 的棋盘,有多种不同的摆放皇后的方式,而有些摆法可能会导致皇后之间发生攻击,有些摆法则不会。

因此,塔子哥需要找到所有满足条件的摆法,以便让他更好地研究 n n n 皇后问题,你能帮塔子哥求出有多少种放置方案吗?

输入描述

第一行输入一个正整数 n n n ,代表棋盘大小。

接下来的 n n n 行,每行输入一个仅由 $. $ 和 ∗ * 组成的字符串,其中 ∗ * 代表放置了一个皇后, . . . 代表未放置皇后。

保证输入的棋盘中没有两个皇后会互相攻击。

1 ≤ n ≤ 1000 1\le n\le 1000 1n1000

输出描述

输出塔子哥有多少种放置方案。

样例

输入

3
.*.
...
...

输出

2

思路

暴力 O ( n 3 ) O(n^3) O(n3)不可取.我们先扫描一遍棋盘。用 r , c r,c r,c 数组来统计第i行/第i列有多少个皇后。对于处于同一正副对角线的两点,有如下规律:

正对角线:两点的横纵坐标之差x-y相等.所以用x-y来对正对角线编号

副对角线:两点的横纵坐标之和相等.所以用x+y来对正对角线编号

所以再使用 x , y x,y x,y 数组来记录第i个正负对角线的皇后个数。

预处理完之后,枚举每个点 i , j i,j i,j , check一下 r [ i ] , c [ j ] , x [ i − j ] , y [ i + j ] r[i],c[j],x[i-j],y[i+j] r[i],c[j],x[ij],y[i+j] 是不是全为0即可。 全为0就代表可行,然后计数。

最后,注意一开始局面就不合法的情况。这种情况需要输出0并提前结束程序!

代码

C++

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 1005;
int a[maxn][maxn];
// 记录行,列,正负对角线的皇后个数
int c[maxn] , r[maxn] , x[maxn * 2] , y[maxn * 2];
int main()
{
    int n;
    cin >> n;
    bool ok = true;
    for (int i = 1 ; i <= n ; i++){
        string t;
        cin >> t;
        t = '#' + t;
        for (int j = 1 ; j <= n ; j++){
            if (t[j] == '*'){
                a[i][j] = 1;
                if (r[i] || c[j] || x[i - j + n] || y[i + j]){
                    ok = false;
                }
                r[i]++;
                c[j]++;
                x[i - j + n]++;
                y[i + j]++;
            }
        }
    }
    if (!ok){
        cout << "0" << endl;
        return 0;
    }
    int cnt = 0;
    for (int i = 1 ; i <= n ; i++){
        for (int j = 1 ; j <= n ; j++){
            if (a[i][j] == 1) continue;
            if (r[i] || c[j] || x[i - j + n] || y[i + j]) continue;
            cnt ++;
        }
    }
    cout << cnt << endl;
    return 0;
}

java

import java.util.*;
public class Main{
    public static void main(String args[]){
        queen();
    }
    public static void queen(){
        Scanner scanner=new Scanner(System.in);
        int n=scanner.nextInt();
        scanner.nextLine();
        HashSet<Integer> row=new HashSet<>();
        HashSet<Integer> col=new HashSet<>();
        HashSet<Integer> dia1=new HashSet<>();
        HashSet<Integer> dia2=new HashSet<>();
        int c;
        for(int i=0;i<n;i++){
            String s=scanner.nextLine();
            c=s.indexOf("*");
            if(c!=-1){
                row.add(i);
                col.add(c);
                dia1.add(i+c);
                dia2.add(i-c);
            }
        }
        int count=0;
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){
                if(row.contains(i)||col.contains(j)||dia1.contains(i+j)||dia2.contains(i-j)){
                    continue;
                }
                count++;
            }
        }
        System.out.println(count);
    }
    
}

python

import sys

'''
6
.*....
......
......
.....*
......
*.....
'''

def dataProcess():
    n = int(input())
    grid = []
    for i in range(n):
        temp = input()
        grid.append(list(temp))
    return n,grid

# I only add one queen for next backtracing operation
def nQueen(n, grid):
    c = [0] * n
    r = [0] * n
    x = [0] * 2 * n
    y = [0] * 2 * n
    a = [[0 for i in range(n)] for j in range(n)]
    ans = 0
    for i in range(n):
        for j in range(n):
            if grid[i][j] == "*":
                a[i][j] = 1
                r[j] += 1
                c[i] += 1
                x[i-j+n] += 1
                y[i+j] += 1
    for i in range(n):
        for j in range(n):
            if a[i][j] == 1:
                continue
            if c[i]!=0 or r[j]!=0 or x[i-j+n]!=0 or y[i+j]!=0:
                continue
            ans += 1        
    return ans


if __name__ == "__main__":
    n,grid = dataProcess()
    ans = nQueen(n, grid)
    print(ans)

js

const lines = [];
const readline = require('readline');
const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
});


(async () => {
  for await (const line of rl) {
    lines.push(line);
  }

  const n = parseInt(lines[0]);

  let res = 0;

  const grid = lines.slice(1).map(l => l.split(''));

  const preProcessing = () => {
    const col = new Map();
    const row = new Map();
    const diag1 = new Map();
    const diag2 = new Map();

    for (let i = 0; i < n; i++) {
      for (let j = 0; j < n; j++) {
        if (grid[i][j] === '*') {
          col.set(j, true);
          row.set(i, true);
          diag1.set(i + j, true);
          diag2.set(i - j, true);
        }
      }
    }

    return [col, row, diag1, diag2];
  }

  const [col, row, diag1, diag2] = preProcessing();

  for (let i = 0; i < n; i++) {
    for (let j = 0; j < n; j++) {
      if (!(col.get(j) || row.get(i) || diag1.get(i + j) || diag2.get(i - j))) {
        res += 1;
      }
    }
  }

  console.log(res);
})();

题目内容均收集自互联网,如如若此项内容侵犯了原著者的合法权益,可联系我: (CSDN网站注册用户名: 塔子哥学算法) 进行删除。

米哈游Java后端笔试真题是面向Java后端开发岗位的一套笔试题目,旨在考察应聘者对Java后端开发的理解和应用能力。 这套笔试题目往往包含以下几个方面的内容: 1. Java语言基础:主要考察Java的基本语法、面向对象编程、常用类库等方面的知识。例如,常见的有关Java语言基础的题目有:反射机制的理解和应用、线程的创建和使用、异常处理等。 2. 数据库相关知识:主要考察应聘者对数据库的基本理解和SQL的使用能力。例如,常见的数据库相关题目有:数据库事务的概念和应用、数据库索引的优化策略、SQL语句的编写和调优等。 3. Web开发框架:主要考察应聘者对常用的Web开发框架的理解和应用能力。例如,常见的Web开发框架题目有:Spring框架的注解使用、MyBatis的配置和映射关系等。 4. 系统设计和优化:主要考察应聘者对大型系统设计和性能优化的能力。例如,常见的系统设计和优化题目有:数据库连接池的设计和实现、分布式系统的负载均衡策略、系统性能调优等。 总的来说,米哈游Java后端笔试真题是一套综合考察Java后端开发能力的题目,内容涵盖了Java语言基础、数据库相关知识、Web开发框架以及系统设计和优化等方面。应聘者需要具备扎实的Java编程基础,熟悉常用的开发框架和工具,以及对大型系统的设计和性能优化有一定的了解。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

塔子哥学算法

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值