【算法题】机试指南-基础篇

本文仅供个人学习使用,免费分享。每日更新,建议关注收藏!
目前[机试指南]本系列已经达到字数10w+,所以按原每个章节拆开发布,点击目录跳转。

本站友情链接:

  1. c/c++算法题指南
    严书代码
    c/c++大复习1
    c/c++大复习2
  2. python算法题指南
    牛客华为机试103精华
    python输入输出大全
    python语法
    PAT甲级真题刷题笔记 共179道
  3. python官方文档
    python官方文档
  4. 机试指南系列
    基础篇
    贪心篇
    递归分治搜索篇
    数据结构进阶篇(树/图/优先队列)
    数学问题篇
    动态规划篇
    STL篇

须知

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

评判结果

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

what the oj returns tip
Accepted yes!
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,则跳出循环,不再继续算法处理。

3.输入输出部分

python汇总
leecode中的关于python题解的输入输出
类里的函数最后结果要用return返回
同一个类中有多个函数时,要类名.函数名()引用
return Solution.daysBetweenDates(self,date1,date2) 
#类名solution

还有一种要记牢的好用的输入方法
for line in sys.stdin:
    a = line.split()
c c++汇总
#include<iostream>
#include<cstdio>
#include<string>
using namespace std;
int main(){
   
	string str;
	while(getline(cin,str))//这样的好处是不会遇到串中空格录入不进去
}

c c++输入输出部分 链接

可暴力求解的题目

枚举

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

题目: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/

思路汇总:

  1. 已知今天的日期和星期几,计算给定日期与当前日期的差值,对7取模;利用上题的日期差值代码继续实现功能

  2. python万能的库函数

  • UTC
    python文档中出现很多次UTC,这个解释一下:
    洋名是:Universal Time Coordinated。
    UTC时间,协调世界时,又称世界统一时间、世界标准时间、国际协调时间。是从1970年1月1日0时0分0秒开始记录到现在的累加的秒数。
    因此,我如果读出的值是1,那么转为日历时间,就是1970年1月1日0时0分1秒。
    我如果读出的值是60,那么转为日历时间,就是1970年1月1日0时1分0秒。

  • python中datetime库

    • strftime() 和 strptime()
      str f time功能:将日期对象->str
      str p time功能:将str解析(parse)成日期对象
    • date /time /datetime区别
      date 日期:包含datetime
      time时间
      datetime两者的结合
    • class datetime.timedelta
      得到两个 datetime 或 date 实例之间的差值(微秒级精度),即支持与 date 和 datetime 对象进行特定的相加和相减运算(见下文)。
      class datetime.timedelta(days=0, seconds=0, microseconds=0, milliseconds=0, minutes=0, hours=0, weeks=0)
      所有参数都是可选的并且默认为 0。 这些参数可以是整数或者浮点数,并可以为正值或者负值。
      days指的是几天前-/几天后+,其他参数同理
    • 星期几函数
date.weekday()
返回一个整数代表星期几,星期一为0,星期天为6。
例如, date(2002, 12, 4).weekday() == 2,表示的是星期三。

date.isoweekday()
返回一个整数代表星期几,星期一为1,星期天为7。
例如:date(2002, 12, 4).isoweekday() == 3,表示星期三。
now=datetime.datetime.now()
now-</
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

七灵微

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

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

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

打赏作者

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

抵扣说明:

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

余额充值