本文仅供个人学习使用,免费分享。每日更新,建议关注收藏!
本站友情链接:
- c/c++算法题指南
严书代码
c/c++大复习1
c/c++大复习2 - python算法题指南
牛客华为机试103精华
python输入输出大全
python语法
目录
须知
本文所选题目均含有原题地址,可直接获取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,则跳出循环,不再继续算法处理。
精选分类
可暴力求解的题目
枚举
枚举简单的都省略,注意对枚举量的优化即可(防止超时间)。
题目: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/
在这里插入代码片
其他模拟
基础:排序查找
基础:字符串
STL
STL定义了强大的、基于模板的、可复用的组件,实现了许多通用的数据结构及处理这些数据结构的算法。其中包含三个关键组件——容器(container,流行的模板数据结构)、迭代器(iterator)和算法(algorithm)。
容器是用来管理某一类对象的集合。C++ 提供了各种不同类型的容器,比如 deque、list、vector、map 等。
迭代器 用于遍历对象集合的元素。这些集合可能是容器,也可能是容器的子集。
算法作用于容器。它们提供了执行各种操作的方式,包括对容器内容执行初始化、排序、搜索和转换等操作。