本文仅供个人学习使用,免费分享。每日更新,建议关注收藏!
目前[机试指南]本系列已经达到字数10w+,所以按原每个章节拆开发布,点击目录跳转。
本站友情链接:
- c/c++算法题指南
严书代码
c/c++大复习1
c/c++大复习2 - python算法题指南
牛客华为机试103精华
python输入输出大全
python语法
PAT甲级真题刷题笔记 共179道 - python官方文档
python官方文档 - 机试指南系列
基础篇
贪心篇
递归分治搜索篇
数据结构进阶篇(树/图/优先队列)
数学问题篇
动态规划篇
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
现成模版以及提示
- reverse数字反转
int reverse(int x){
int revx=0;
while(x!=0){
revx*=10;
revx+=x%10;
x/=10;
}
return revx;
}
- 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))//这样的好处是不会遇到串中空格录入不进去
}
可暴力求解的题目
枚举
枚举简单的都省略,注意对枚举量的优化即可(防止超时间)。
题目: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)
刚开始没看懂这题规律,后来发现:
最终结果的画布大小=(原画布放大比例) 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/
思路汇总:
-
已知今天的日期和星期几,计算给定日期与当前日期的差值,对7取模;利用上题的日期差值代码继续实现功能
-
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指的是几天前-/几天后+,其他参数同理 - 星期几函数
- strftime() 和 strptime()
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-</