笔试见过的题型

【过河问题】阿里笔试
题目描述: N N N个人一起过河,但只有一条船,每条船每次最多只能容纳两人。过河的速度等于两人中体重最大的那一个人的体重,若只有一人过河,则速度即为该人体重。现给出这 N N N个人的体重,请你计算出这 N N N个人过河的最短时间。
思路:将每个人的过河时间按升序排好序。

  • 如果只有一个人过河,那么过河时间为该人体重。
  • 如果两个人过河,那么过河时间为两人中体重最大的那个。
  • 如果三个人过河,那最优策略应该为最慢和最快的人过河(时间 T 2 T2 T2),最快的返回(时间 T 0 T0 T0),然后最快和次慢的人过河(时间 T 1 T1 T1),那么过河时间应该为三人单独过河的时间总和 T 0 + T 1 + T 2 T0+T1+T2 T0+T1+T2
  • 如果四个人过河,过河时间分别为 T 0 , T 1 , T 2 , T 3 T0,T1,T2,T3 T0,T1,T2,T3,那么有两种策略:
    (1)最快和次快的人过河(时间 T 1 T1 T1),最快的人返回(时间 T 0 T0 T0),然后最慢和次慢的人过河(时间 T 3 T3 T3),次快的人返回(时间 T 1 T1 T1),最后最快和次快的人过河(时间 T 1 T1 T1)。总时间: T 1 + T 0 + T 3 + T 1 + T 1 T1+T0 + T3 +T1+T1 T1+T0+T3+T1+T1
    (2)最慢和最快的人过河(时间 T 3 T3 T3),最快的人返回(时间 T 0 T0 T0),然后次慢和最快的人过河(时间 T 2 T2 T2),最快的人返回(时间 T 0 T0 T0),最后最快和次快的人过河(时间 T 1 T1 T1)。总时间: T 3 + T 0 + T 2 + T 0 + T 1 T3+T0+T2+T0+T1 T3+T0+T2+T0+T1
    最后一趟总是最快和次快的人过河。因此比较这两种方案哪一种更优,则是比较 2 × T 1 2\times T1 2×T1(第一种)和 T 0 + T 2 T0+T2 T0+T2(第二种)的大小。如果 2 × T 1 > T 0 + T 2 2\times T1>T0+T2 2×T1>T0+T2,则选择第二种方案,反之,这选择第一种,二者相等,则两个方案用时相同。
  • 如果 N N N个人过河( N > 4 N>4 N>4),则这个问题可以划为多个四人过河( N N N为奇数,则最后为三人过河)子问题。因为最重的一人过河时间是不会受任何其他人的干扰,因此在这个过程中,应该用最快和次快的人来减少返程的时间,而与最重的人搭配,必然是次重的人,否则次重的人会成为下次最重的人,这样只会加长过河时间。而在四人过河这个子问题中,则可以根据上述提到的两种方案择优而取。
def GuoHe(N,weight):
    weight.sort()
    if N < 3:
        Times = weight[N-1]
        return Times
    if N == 3:
        Times = sum(weight)
        return Times
    Times = 0
    while N >= 4:
        T1 = weight[0] + 2*weight[1] + weight[N-1]
        T2 = weight[N-1] + weight[N-2] + 2*weight[0]
        if T1>T2:
            Times = Times + T2
        else:
            Times = Times + T1
        N -= 2
    if N==3:
        Times = Times + sum(weight[0:3])
        return Times
    # 最后一趟最快和次快的人过河时间要加上
    if N==2:
        return Times + weight[1]
# 测试样例的个数
T = int(input())
for i in range(T):
    # 人数
    N = int(input())
    #每人体重
    weight = list(map(int,input().split()))
    Times = GuoHe(N,weight)
    print(Times)

【顺时针打印矩阵】华为笔试
题目描述: 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下 4 × 4 4\times4 4×4矩阵: [ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ] \begin{bmatrix} 1 & 2 & 3 & 4 \\ 5&6&7&8\\9&10&11&12\\13&14&15&16\end{bmatrix} 15913261014371115481216 ,则依次打印出数字 1 , 2 , 3 , 4 , 8 , 12 , 16 , 15 , 14 , 13 , 9 , 5 , 6 , 7 , 11 , 10 1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10 1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10
思路:每次输出完矩阵第一行后,将矩阵进行旋转,再输出第一行。例如 4 × 4 4\times4 4×4矩阵输出第一行后为
[ 5 6 7 8 9 10 11 12 13 14 15 16 ] \begin{bmatrix}5&6&7&8\\9&10&11&12\\13&14&15&16\end{bmatrix} 5913610147111581216,将其旋转为 [ 8 12 16 7 11 15 6 10 14 5 9 13 ] \begin{bmatrix}8&12&16\\7&11&15\\6&10&14\\5&9&13\end{bmatrix} 8765121110916151413pop掉第一行后再旋转为 [ 15 14 13 11 10 9 7 6 5 ] \begin{bmatrix}15&14&13\\11&10&9\\7&6&5\end{bmatrix} 15117141061395,再pop第一行,再旋转,如此反复,知道matrix为空。

# -*- coding:utf-8 -*-
class Solution:
    # matrix类型为二维列表,需要返回列表
    def printMatrix(self, matrix):
        # write code here
        res = []
        while matrix:
            res += matrix.pop(0)
            if not matrix or not matrix[0]:
                break
            matrix = self.turn(matrix)
        return res
    # 将当前矩阵翻转过来,行数变成列数,列数变成行数
    def turn(self,matrix):
        # 矩阵行数
        num_r = len(matrix)
        num_c = len(matrix[0])
        newmat = []
        # 第末列的变成第一行,于是列数倒序。行数正序
        for i in range(num_c-1,-1,-1):
            newmat2 = []
            for j in range(num_r):
                newmat2.append(matrix[j][i])
            newmat.append(newmat2)
        return newmat

【螺旋矩阵输出】
先输入得到一个 n × n n\times n n×n大小的斐波那契数列(第一项、第二项为1),然后将数列螺旋打印输出,如 n = 3 n=3 n=3,则输出为
[ 1 1 2 21 34 3 13 8 5 ] \begin{bmatrix}1&1&2\\21&34&3\\13&8&5\end{bmatrix} 121131348235
思路:螺旋式填充这个 n × n n\times n n×n矩阵。
Python代码如下:


def fb(n):
    res = [1,1]
    f1 = res[0]
    f2 = res[1]
    for i in range(2,n):
        f1, f2 = f2, f1+f2
        res.append(f2)
    return res

def printMatrix(res):
    n = len(res)
    m = int(n**0.5)
    arr = [[0]*m for _ in range(m)]
    i = 0
    j = 0
    arr[i][j] = res[0]
    num = 1
    while num<n:
        # 从最上面一行开始
        while j+1<m and arr[i][j+1]==0:
            arr[i][j+1] = res[num]
            j += 1
            num += 1
        # 从最右一列开始
        while i+1<m and arr[i+1][j]==0:
            arr[i+1][j] = res[num]
            i += 1
            num += 1
        # 从最下面一行开始
        while j-1>=0 and arr[i][j-1]==0:
            arr[i][j-1] = res[num]
            j -= 1
            num += 1
        # 从最上面一行开始
        while i-1>=0 and arr[i-1][j]==0:
            arr[i-1][j] = res[num]
            i -= 1
            num += 1
    return arr

n = int(input())
res = fb(n)
arr = printMatrix(res)
print(arr)

C语言代码如下:

#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>

int main()
{
    int N,i=1;
    int a[100] = {1,1};
    printf("斐波那契数列长度:");
    scanf("%d",&N);


    for(i=2;i<N;i++)
    {
        a[i] = a[i-1] + a[i-2];
    }

    for(i=0;i<N;i++)
    {
        printf("%2d\n",a[i]);
    }


    int m = sqrt(N);
    int arr[10][10];
    //初始化arr全为0,需头文件string.h
    memset(arr,0,sizeof(arr));

    int r=0,c = 0;
    arr[r][c] = a[0];
    int num = 1;
    while(num<N)
    {
        while(c+1<m&&arr[r][c+1]==0)
            arr[r][++c] = a[num++];
        while(r+1<m&&arr[r+1][c]==0)
            arr[++r][c] = a[num++];
        while(c-1>=0&&arr[r][c-1]==0)
            arr[r][--c] = a[num++];
        while(r-1>=0&&arr[r-1][c]==0)
             arr[--r][c] = a[num++];
    }

    for(int i=0;i<m;i++)
    {
        for(int j=0;j<m;j++)
        printf("%2d",arr[i][j]);

        printf("\n");

    }


}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值