【算法题】机试指南篇

本文仅供个人学习使用,免费分享。每日更新,建议关注收藏!

本站友情链接:

  1. c/c++算法题指南
    严书代码
    c/c++大复习1
    c/c++大复习2
  2. python算法题指南
    牛客华为机试103精华
    python输入输出大全
    python语法

须知

本文所选题目均含有原题地址,可直接获取c/c++以及python版解析。

评判结果

评判结果就是提交代码后系统返回的结果,这个不仅仅只是一个结果,还可以是一个debug的提示。

what the oj returnstip
Acceptedyes!
Wrong Answer解决方案:1.考虑特殊数据、边界数据、溢出 2.算法本身正确性
Presentation Error格式错,建议重新打印输出看下是否符合格式
Time Limit Exceeded死循环,边界数据,复杂度过高需要优化
Runtime Error访问内存地址越界如下标越界,除0,调用禁止使用的函数,递归过深等的栈溢出
Compile Error程序本身语法错误且无法进行编译
Memory Limit Exceeded空间复杂度过高,死循环或申请空间过量
Output Limit Exceeded死循环、关闭调试信息

考试规则提前了解

是全答对才有分数,还是答对多少测试点就能达到对应比例的分数,这点在备考期间很重要。

语言与IDE选择

最常见的是c/c++对应codeblocks
python推荐vscode

现成模版以及提示

  1. reverse数字反转
int reverse(int x){
	int revx=0;
	while(x!=0){
		revx*=10;
		revx+=x%10;
		x/=10;
	}
	return revx;
}
  1. while(scanf(“%d”,&h)!=EOF)的含义
    EOF通常被定义为-1,表示文件结束符。它用于指示已到达文件的末尾或输入流的末尾。
    scanf函数是有返回值的,返回的是被输入函数成功赋值的变量个数。当输入结尾时scanf函数返回EOF,则跳出循环,不再继续算法处理。

精选分类

可暴力求解的题目

枚举

枚举简单的都省略,注意对枚举量的优化即可(防止超时间)。

题目:old bill
点击题目转到判题平台

from re import I
import sys
i=0
n=0
sum=0
def count(n,x,y,z):
    first=9
    last=9
    while first:
        if last==0:
            last=9
            first-=1
        else:
            last-=1
        sum=int(first)*10000+int(x)*1000+int(y)*100+int(z)*10+last
        if int(sum/n)*int(n)==int(sum):
            print(first,last,int(sum/n)) #,分割就已经自带空格了
            return 2
    return -1 #注意这里的没有可能的情况 要特别输出0
        

for line in sys.stdin:
    a = line.split()
    i+=1
    if (i%2):
        n=a[0]
    else:
        if(count(int(n),int(a[0]),int(a[1]),int(a[2]))==-1):
            print(0)
    #print(a,i)

图形排版

这种题目核心:找数学规律,注意输出的格式。

叠筐 杭电oj

题目描述:
把一个个大小差一圈的筐叠上去,使得从上往下看时,边筐花色交错。

输入:
输入一个三元组,分别是外筐尺寸n(n为满足0<n<80的奇整数),中心花色字符,外筐花色字符,后两者都为ASCII可见字符。

输出:
输出叠在一起的筐图案,中心花色和外筐花色字符从内层起交错相叠,多筐相叠时,最外筐的角总是被打磨掉,叠筐与叠筐之间应有一层间隔。
在这里插入图片描述
首先这个图怎么看的,它总体是一个层层圈包的形态,最后去掉最外层4个角
本题思路在于构造两次二重循环,第一次二重循环在于每次按行放正确元素,第二次二重循环在于每次按列放正确元素,渲染步骤如下:
在这里插入图片描述
也就是说 第一次循环已经把两个三角形的矩阵元素放好了,第二次循环放好阴影区域的两个三角形中的元素。

def print_box(n_,a,b):
    array_ = [[' ' for k in range(n_)] for i in range(n_)]
    book = [[0 for k in range(n_)] for i in range(n_)]
    num=0
    true_a=a
    true_b=b
    for i in range(n_):
        for j in range(num,n_-num):
            if(book[i][j]==0):
                array_[i][j]=b
                book[i][j] == 1
            if (book[n_-num-1][j] == 0):
                array_[n_-num-1][j] = b
                book[n_-num-1][j] == 1
        num+=1
        a, b = b, a
    #print(array_)

    a,b=true_a,true_b
    num=0
    for i in range(n_):
        for j in range(num,n_-num):
            if(book[j][i]==0):
                array_[j][i]=b
                book[j][i] == 1
            if (book[j][n_-num-1] == 0):
                array_[j][n_-num-1] = b
                book[j][n_-num-1] == 1
        num+=1
        a, b = b, a
    #print(array_)
    array_[0][0]=' '
    array_[0][n_-1] = ' '
    array_[n_ - 1][0] = ' '
    array_[n_-1][n_ - 1] = ' '
    
    for m in range(n_):
        for n in range(n_):
            print(array_[m][n],end='')
        print('\n')

if __name__ == '__main__':
    line = input()
    line=line.split()
    n=line[0]
    a=line[1]#center
    b=line[2]#outer

    print_box(int(n),a,b)

repeater北大复试

刚开始没看懂这题规律,后来发现:
最终结果的画布大小=(原画布放大比例) x (原画布放大比例),但这是不可一次实现的,所以用不上这个公式
应用递推来做,从原模版1倍~level倍,逐渐放大,即:
用一个二维数组来存储基本图形,之后遍历图形,level从0开始,遇到字符就用基本图形去填充结果,遇到空格就用len*len个空格(len=n的level次方)去填充,循环一次更新结果,使结果作为新的模板,直到level达到输入的要求。

输入:
3
# #
 # 
# #
1
3
# #
 # 
# #
3
4
 OO 
O  O
O  O
 OO 
2
0
输出:
# #
 # 
# #
# #   # #         # #   # #
 #     #           #     # 
# #   # #         # #   # #
   # #               # #   
    #                 #    
   # #               # #   
# #   # #         # #   # #
 #     #           #     # 
# #   # #         # #   # #
         # #   # #         
          #     #          
         # #   # #         
            # #            
             #             
            # #            
         # #   # #         
          #     #          
         # #   # #         
# #   # #         # #   # #
 #     #           #     # 
# #   # #         # #   # #
   # #               # #   
    #                 #    
   # #               # #   
# #   # #         # #   # #
 #     #           #     # 
# #   # #         # #   # #
     OO  OO     
    O  OO  O    
    O  OO  O    
     OO  OO     
 OO          OO 
O  O        O  O
O  O        O  O
 OO          OO 
 OO          OO 
O  O        O  O
O  O        O  O
 OO          OO 
     OO  OO     
    O  OO  O    
    O  OO  O    
     OO  OO    
      
# 大神写的
try:
    while True:
        num = int(input())
        if num == 0:
            break
        result = []  # 输出结果
        template = []  # 起初模板(不变)
        for i in range(num):
            template.append(input())
            result.append(template[i])
        sign = result[0].split()[0][0]  # 得到符号
        zoomsNum = int(input())
        for i in range(1, zoomsNum):  # i为放大的倍数
            replaceNum = num ** i#画布大小
            example = []  # 保存着前一个倍数的模板
            blanks = " " * replaceNum  # 当前倍数比较起初模板空格被放大的倍数
            for j in range(num):  # j为起初模板对于的行
                for k in range(replaceNum):  # k是对应起初模板的一行中被放大倍数后的行数
                    if j == 0:
                        example.append(result[k])  # 保存着前一个倍数的模板
                        result[k] = template[j].replace(" ", blanks)  # 在起初第一行模板不需要增加行数,所以只需要放大空格和符号sign就好
                    else:
                        result.append(template[j].replace(" ", blanks))
                    signLines = example[k]  # 把每一个符号位替换成上一个倍数对应的行
                    result[k + j * replaceNum] = result[k + j * replaceNum].replace(sign, signLines)
        for i in result:
            print(i)
except Exception:
    pass

#我自己根据自己的思路写的: 已ac
import sys
template_ = []

def big(n, t, result):  # 原模版长度,模版,结果
    new_num = len(result) * n  # 新画布行数
    new_result = [[] for i in range(new_num)]

    for k in range(len(result)):  # 遍历模版行数 t[k]表示其中一行
        todo_line = result[k]
        if(type(todo_line)==list):
            todo_line = ''.join(todo_line)  # 当前处理的这行

        for m in range(len(todo_line)):  # 依次取模版的每一个字符
            new_i1 = k * len(t)
            new_i2 = (k + 1) * len(t)
            if (todo_line[m] == ' '):
                for count in range(new_i1, new_i2):
                    new_result[count].append(' ' * len(t))
            else:
                t_line = 0
                if (t_line == len(t)): t_line = 0
                for count in range(new_i1, new_i2):
                    new_result[count].append(t[t_line])
                    t_line += 1
    return new_result


def build_result(n, t, s):  # 原模版长度,模版,倍数
    result = t
    if (s == 1): return t
    for i in range(1, s):
        result = big(n, t, result)
    return result


def print_result(r):
    for i in range(len(r)):
        print(''.join(r[i]))


for line in sys.stdin:
    num = int(line)
    if (num == 0): break
    for i in range(0, num):
        template_.append(sys.stdin.readline().strip('\n'))
    scale = int(input())
    print_result(build_result(num, template_, scale))
    template_=[]

helloworld for u
思路:已知满足公式 2x+n2=N+2,x为u的高度,x尽可能大,且n2>=x>=2,N>=n2>=3,N已知,
则要使n2尽可能小,所以先从n2=3开始尝试,看能否得到整数x。

content=input()
N=len(content)

n2=3
while n2<N:
    num=N+2-n2
    if(num%2==0):
        height=int(num/2)
        if(height<=n2):break
    n2+=1
result=[[]for i in range(height)]
result[-1].append(content[height-1:N-height+1])
for j in range(height-1):
    result[j].append(content[j])
    result[j].append(' '*(n2-2))
    result[j].append(content[N-1-j])
#print(result)
#print(N,height,n2)
for k in result:
    print(''.join(k))

日期问题

常见处理思想:
1. 预处理,将每月天数事先存储在数组/list中;
int daytab[2][13]={ #c/c++版本
{0,31,28,31,30,31,30,31,31,30,31,30,31},
{0,31,29,31,30,31,30,31,31,30,31,30,31}
};
daytab=[ #python中常用list构造多维数组
[0,31,28,31,30,31,30,31,31,30,31,30,31],
[0,31,29,31,30,31,30,31,31,30,31,30,31]
]
3. 需要注意闰年的2月有29天,
闰年判断规则:(year%4==0 && year%100 !=0)|| (year%400 ==0),true为闰年

日期差值
https://leetcode.cn/problems/number-of-days-between-two-dates/description/

def leap_year(year):
    if (year % 400 == 0 or (year % 4 == 0 and year % 100)):
        return 1
    else:
        return 0


class Solution:

    def daysBetweenDates(self, date1: str, date2: str) -> int:
        date1 = [int(i) for i in date1.split('-')]
        date2 = [int(i) for i in date2.split('-')]
        days = [[0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],
                [0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]]
        number = 0

        # 默认date1小于date2
        if (date1[0] > date2[0]):
            date1, date2 = date2, date1
        elif (date1[0] == date2[0] and date1[1] > date2[1]):
            date1, date2 = date2, date1
        elif (date1[0] == date2[0] and date1[1] == date2[1]):
            return(abs(date1[2]-date2[2]))

        while(1):#至少月份不同

            cur = leap_year(date1[0])
            if(date1[2] != 1):
                number += days[cur][date1[1]]
                number -= date1[2]
                date1[1] += 1
                date1[2] =1
                number+=1
                if (date1[1] == 13):
                    date1[0] += 1
                    date1[1] = 1
                    continue #勿忘这条

            if(date1[0]==date2[0] and date1[1]==date2[1]):
                break

            while (1):
                number += days[cur][date1[1]]
                date1[1] += 1
                if(date1[1]==13):
                    date1[0]+=1
                    date1[1]=1
                    break
                elif(date1[0]==date2[0] and date1[1]==date2[1]):
                    break

        number += abs(date1[2]-date2[2])

        return number

day of week
https://leetcode.cn/problems/day-of-the-week/description/

在这里插入代码片

其他模拟

基础:排序查找

基础:字符串

STL

STL定义了强大的、基于模板的、可复用的组件,实现了许多通用的数据结构及处理这些数据结构的算法。其中包含三个关键组件——容器(container,流行的模板数据结构)、迭代器(iterator)和算法(algorithm)。

容器是用来管理某一类对象的集合。C++ 提供了各种不同类型的容器,比如 deque、list、vector、map 等。
迭代器 用于遍历对象集合的元素。这些集合可能是容器,也可能是容器的子集。
算法作用于容器。它们提供了执行各种操作的方式,包括对容器内容执行初始化、排序、搜索和转换等操作。

向量vector

队列queue

栈stack

贪心

简单贪心

区间贪心

递归与分治

搜索

深搜

广搜

数据结构进阶

二叉树

二叉排序树

优先队列

散列表

动态规划

递归求解

最大连续子序列和

最长递增子序列

最长公共子序列

背包问题

其他问题

图论

并查集

最小生成树

最短路径

拓扑排序

关键路径

数学问题

进制转换

最大公约数&最小公倍数

质数

质因数

快速幂

矩阵、矩阵快速幂

高精度整数

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值