20230319数据开发笔试(米哈游、携程..)

在这里插入图片描述

1. 岛屿数量问题

他是个色盲,蓝绿不分。连通块,上下左右连接,则认为是一个连通块。
输入grid=[ [“R”, “R”, “G”, “G”, “B”, “B”],
[“R”, “G”, “B”, “G”, “R”, “R”]]
正常人会认为有6个连通块,但是由于他是色盲,会导致他只看到3个连通块,现在求解任何一个矩阵,他会比正常人少看多少个连通块。
分析:
R不会影响差值,结果就是B岛屿数量+G岛屿数量-BG联合形成的岛屿数量

def numIslands(grid,mark) -> int: #grid 为矩阵,mark为印记
    dir=[[-1,0],[0,1],[1,0],[0,-1]]
    ans=0
    def dfs(x,y):
        grid[x][y]='0'
        for k in range(4):
            dx=x+dir[k][0]
            dy=y+dir[k][1]
            if dx>=0 and dx<len(grid) and dy>=0 and dy<len(grid[0]) and grid[dx][dy]==mark:
                dfs(dx,dy)

    for i in range(len(grid)):
        for j in range(len(grid[0])):
            if grid[i][j]==mark:
                dfs(i,j)
                ans+=1
    return ans

例子:

arr=[[1,0,0],[1,1,0],[0,0,1]]
numIslands(arr,1) #即数数1的连通块有几个

那么本题的解法

grid=[["R", "R", "G", "G", "B", "B"],["R", "G", "B", "G", "R", "R"]]
#此处使用了列表推倒式,将色盲眼中的颜色进行了替换
grid_semang=[[x if x=="R" else "G" for x in y] for y in grid]
numIslands(grid,'B')+numIslands(grid,'G')-numIslands(grid_semang,'G')

2.将数据排序

// 输入两个数n,m,输出 n * m 的按列递增的矩阵,超出9的部分从0开始
// 例:n=3,m=4
// 0 3 6 9
// 1 4 7 0
// 2 5 8 1
分析:利用模运算即可

n,m=map(int,input().split())
word=list(range(10))
ans=[[0 for _ in range(m)] for _ in range(n)]
cnt=0
for j in range(m):
    for i in range(n):
        ans[i][j]=word[cnt%10]
        cnt+=1
for i in ans:print(i)

结果:

3 4. #输入的m 和 n
[0, 3, 6, 9]
[1, 4, 7, 0]
[2, 5, 8, 1]
3.n皇后问题

首先来看一下皇后们的约束条件:
1.不能同行
2.不能同列
3.不能同斜线
分析:采用回溯的方法,行是深度,列是宽度,注意python的拷贝

from copy import deepcopy
def backtacking(n,row,chessboard):
    if row==n:
#         print(chessboard)
#         tmp=chessboard.copy()
        res.append(deepcopy(chessboard))
    for col in range(n):
        if isValid(row,col,chessboard,n):
            chessboard[row][col]='Q'
            backtacking(n,row+1,chessboard)
            chessboard[row][col]='.'

def isValid(row,col,chessboard,n):
    #检查列
    for i in range(row):
        if chessboard[i][col]=='Q':
            return False
    #检查45度
    i=row-1
    j=col-1
    while i>=0 and j>=0:
        if chessboard[i][j]=='Q':
            return False
        i-=1
        j-=1
    #检查135度
    i=row-1
    j=col+1
    while i>=0 and j<n:
        if chessboard[i][j]=='Q':
            return False
        i-=1
        j+=1
    return True


def solveNQueens(n,res):
    chessboard=[['.' for _ in range(n)] for _ in range(n)]
    backtacking(n,0,chessboard)
    return res
    
res=[]
solveNQueens(4,res) 

运行结果:

[[['.', 'Q', '.', '.'],
  ['.', '.', '.', 'Q'],
  ['Q', '.', '.', '.'],
  ['.', '.', 'Q', '.']],
 [['.', '.', 'Q', '.'],
  ['Q', '.', '.', '.'],
  ['.', '.', '.', 'Q'],
  ['.', 'Q', '.', '.']]]
3.1 n 皇后
题目描述

米小游最近在研究 n 皇后问题。 所谓 n 皇后问题,指 n×n 的棋盘中,放置 n 个皇后,满足两两之间不会互相攻击。
每个皇后可以攻击同一行、同一列以及同一 45度角斜线和 135度角斜线上的所有其他皇后。
米小游拿到了一个 n×n 的棋盘,目前已经放置了一些皇后,米小游希望再放置一个皇后, 满足所有的皇后不会互相攻击。
你能帮米小游求出有多少种放置方案吗?

输入描述

第一行输入一个正整数 n ,代表棋盘大小。
接下来的 n 行,每行输入一个仅由 … 和 ∗∗ 组成的字符串,其中 ∗代表放置了一个皇后, .代表未放置皇后。
保证输入的棋盘中没有两个皇后会互相攻击。1≤n≤1000
3
.*.

输出描述

输出米小游有多少种放置方案。2
分析:对棋盘上没有放置皇后的位置进行遍历,判断是否合理。

def isValid(n,row,col,chessboard):
    #查看列
    for i in range(n):
        if chessboard[i][col] != '.':
            return False
    #查看行
    for j in range(n):
        if chessboard[row][j] != '.':
            return False
    #查看45度
    i=row-min(row,col)
    j=col-min(row,col)
    while i<n and j<n:
        if chessboard[i][j] != '.':
            return False
        i+=1
        j+=1
    #查看135度
    i=0
    j=col+row
    while j>=0 and i<n :
        if j<n and chessboard[i][j] != '.':
            return False
        j-=1
        i+=1
    return True

def solvequeen(n,chessboard):
    s=0
    for i in range(n):
        for j in range(n):
            if chessboard[i][j]=='.' and isValid(n,i,j,chessboard):
                s+=1
    return s 

chessboard=[['.','*','.'],['.','.','.'],['.','.','.']]  
solvequeen(3,chessboard)

解法2:遍历有皇后的位置,将其攻击区域改为#,之后计算没有攻击的位数,便是下一个皇后可以放置的方案数

def attck(n,row,col,chessboard):
    #修改列
    for i in range(n):
        chessboard[i][col] = '#'
    #修改行
    for j in range(n):
        chessboard[row][j] = '#'
    #修改45度
    i=row-min(row,col)
    j=col-min(row,col)
    while i<n and j<n:
        chessboard[i][j] = '#'
        i+=1
        j+=1
    #修改135度
    i=0
    j=col+row
    while j>=0 and i<n :
        if j<n :
            chessboard[i][j] = '#'
        j-=1
        i+=1

def solvequeen_2(n,chessboard):
    for i in range(n):
        for j in range(n):
            if chessboard[i][j]=='*':
                attck(n,i,j,chessboard)
                
    s=0          
    for i in chessboard:
        for j in i:
            if j=='.':
                s+=1     
    return s 

chessboard=[['.','*','.'],['.','.','.'],['.','.','.']]  
solvequeen_2(3,chessboard)
4.小明去游乐园

题目描述
游乐场有n个项目,每个项目必须在时间ti前才能玩,玩一个项目需要花一个小时,小明0点进入游乐场
每个项目有对应的积分 玩了能获得积分 没玩要扣除相应的积分 求最多能获得多少分 比如
3
3 1 1
3 6 9
3个项目 分别在3点前 1点前 1点前参加 分别的积分是 3 6 9 算上游玩要花的一个小时 其实是要在 2点 0点 0 点 之前去玩 所以样例最多积分是 9+3-6=6分
思路
该问题类似背包问题,显然最佳策略是尽量的得分,这样扣分也会相对应得减少,总分也会略高。准备一个数组来记录玩的项目的分数,该数组可以存储当前分数的最小值。根据时间进行从低到高的排序,接着进行循环遍历,时间是背包的容量,如果遍历到某个项目比数组中的最小值大,则进行替代。
分析:该题目是加了权重的贪心算法

5.大整数截取

花花有一个很珍贵的数字串,但是它太长了,没有办法保留下来,所以她想截取其中一段保存下来,但是她希望截取下来的这一段数对1000000007取模之后等于Ai,她想知道有多少种截取方案。数字串S中截取一段是指S[L], S[L+1], …, S[R]连起来所形成的十进制数,其中L和R满足1≤L≤R≤|S|。例如S=“1023456789”,S(0,2)=10,S(2,4)=23,S(2,10)=23456789。
输入描述
第一行一个数字串,长度不超过30000。
第二行一个数T,表示询问的数量。(T≤100)
接下来T行,每行一个非负整数Ai,表示询问有多少种截取方案使得其值模1000000007后等于Ai。(0≤Ai<1000000007)
输出描述
共T行,每行一个非负整数,表示方案数。

样例输入

1000000008001
4
8
0
1
10

样例输出

9
39
5
2
def getCountofMod(s,mod,key):
   n=len(s)
   cnt=0
   for i in range(n):
       if s[i] != '0':
           tmp=int(s[i])
           if tmp==key:
               print(tmp)
               cnt+=1
           for j in range(i+1,n):
               tmp=((tmp*10)%mod+int(s[j]))%mod
               if tmp==key:
                   print(s[i:j+1])
                   cnt+=1
   return cnt
s='1000000008001'
mod=1000000007
key=10 
getCountofMod(s,mod,key)

结果:

10
10000000080

2
6最短子串

题目描述
米小游拿到了一个字符串,她想截取一个连续子串,使得该子串中包含至少k个连续的“mihoyo”。 帮米小游求出最短的子串长度,以及对应的子串位置
输入描述
第一行输入两个正整数n和k,用空格隔开。 第二行输入一个长度为n的、仅由小写字母组成的字符串。
输出描述
如果不存在这样一个连续子串,请输出-1。 否则输出两个正整数l,r,代表选取的子串的左下标和右下标(整个字符串左下标为0,右下标为n-1)。 请务必保证选择的连续子串包含至少k个"mihoyo",且长度是最短的。有多解时输出任意即可。
思路:将mihoyo看作一个整体

猜你喜欢

转载自blog.csdn.net/F13122298/article/details/129964653