第一题
问题描述
请问在 1 到 2020 中,有多少个数与 2020 互质,即有多少个数与 2020 的最大公约数为 1。
import math
count=0
for i in range(1,2021):
if(math.gcd(i,2020)==1):
count+=1
print(count)
答案:
800
第二题
问题描述
ASCII 码将每个字符对应到一个数值(编码),用于信息的表示和传输。在 ASCII 码中,英文字母是按从小到大的顺序依次编码的,例如:字母 A 编码是 65, 字母 B 编码是 66,字母 C 编码是 67,请问字母 Q 编码是多少?
答案
81
第四题
问题描述
对于整数 v 和 p,定义 Pierce 序列为:
a[1] = v
a[i] = p % a[i-1]
例如,当 v = 8, p = 21 时,对应的 Pierce 序列为
a[1] = 8
a[2] = 5
a[3] = 1
再往后计算,值变为 0,不在我们考虑的范围内。因此当 v = 8, p = 21 时, Pierce 序列的长度为 3。
当 p 一定时,对于不同的 v 值,Pierce 序列的长度可能不同。当 p = 8 时,若 1<=v<p,最长的 Pierce 序列出现在 v=13时,为(13, 8, 5, 1),长度为 4。
当 p=2021 时,最长的 Pierce 序列出现在 v=1160 时,请问这个序列有多长?
思路:
就按照题目遍历就行了,没什么好说的
count =1
pre = 1160
p=2021
while(2021%pre!=0):
count+=1
pre =(p%pre)
print(count)
答案
12
第五题
问题描述
在 Excel 中,第 1 列到第 26 列的列名依次为 A 到 Z,从第 27 列开始,列名有两个字母组成,第 27 列到第 702
列的列名依次为 AA 到 ZZ。 之后的列再用 3 个字母、4 个字母表示。 请问,第 2021 列的列名是什么?
import itertools
list1 = [chr(i) for i in range(ord('A'),ord('Z')+1)] #
list2=[]
for i in list1:
for j in list1:
list2.append(i+j)
sumvalue=702
for i in list2:
for j in list1:
sumvalue+=1
temp1 = "".join(i)+j
if(sumvalue==2021):
print(temp1)
break
这道题可以首先将AA-ZZ存为一个数组,然后使用一个二层循环进行遍历,直到sumvalue到达2021结束,输出结果
答案
BYS
第六题
问题描述
在书写一个较大的整数时,为了方便看清数位,通常会在数位之间加上逗号来分割数位,具体的,从右向左,每三位分成一段,相邻的段之间加一个逗号。
例如,1234567 写成 1,234,567。
例如,17179869184 写成 17,179,869,184。
给定一个整数,请将这个整数增加分割符后输出。
输入格式
输入一行包含一个整数 v。
输出格式
输出增加分割符后的整数。
样例输入
1234567
样例输出
1,234,567
样例输入
17179869184
样例输出
17,179,869,184
数据规模和约定
对于 50% 的评测用例,0 <= v < 10^9 (10的9次方)。
对于所有评测用例,0 <= v < 10^18 (10的18次方)。
代码
s = input()
sumvalue =0
for i in range(len(s)-1,0,-1): #最后一位不用判断,因为即使有逗号也不应该加
sumvalue+=1
if(sumvalue%3==0):
s = ','.join([s[:i],s[i:]]) #将前i位和后i位中间加一个,
print(s)
第七题
问题描述
斐波那契数列是这样一个数列:它的第一项和第二项都是1,从第三项开始每一项都是前两项的和。
根据以上定义,我们容易计算出斐波那契数列的前几项依次是:1, 1, 2, 3, 5, 8, 13, 21, 34, 55 ……
现在请你计算斐波那契数列第N项是奇数还是偶数?
输入格式
输入的包含一个整数N。
输出格式
如果是奇数输出1,是偶数输出0。
样例输入
10
样例输出
1
提示
找规律。
数据规模和约定
对于所有评测用例,1 <= N <= 1000000000。
解题思路
其实就是找规律,因为也可以观察到规律就是奇数加奇数为偶数,偶数加奇数为奇数,找到规律就是,N为3的倍数时为偶数,其他时候是奇数
第八题
给定一个矩阵 M,由 n 行 m 列组成,第 i 行第 j 列值为 M[i][j]。
定义矩阵 M 的重量为矩阵中所有元素的和,几位weight(M)
请找到矩阵左上角的一个子矩阵S(矩阵的前 r 行中的前 c 列组成),使得这个子矩阵的重量的两倍最接近矩阵 M 重量。即 |2 weight(S)-weight(M)| 最小。
如果有多个子矩阵满足条件,请找出面积 r * c 最小的一个。
如果仍然有多个子矩阵满足条件,请找出其中 r 最小的一个。
输入格式
输入第一行包含两个整数 n, m,表示矩阵的大小。
接下来 n 行,每行 m 个整数,表示给定的矩阵M。
输出格式
输出一行,包含两个整数 r, c,表示子矩阵为矩阵 M 的前 r 行中的前 c 列。
样例输入
3 4
3 0 1 1
1 0 1 1
1 1 -2 4
样例输出
2 3
数据规模和约定
对于 30% 的评测用例,1 <= n, m <= 20, -10 <= M[i][j] <= 10。
对于 50% 的评测用例,1 <= n, m <= 100, -100 <= M[i][j] <= 100。
对于所有评测用例,1 <= n, m <= 1000, -1000 <= M[i][j] <= 1000。
思路
不能用暴力算出每个矩阵的的重量,因为得重复遍历很多次,这种矩阵题很多都可以用前缀和,相当于二维前缀和,定义dp[i][j]为前i行前j列的矩阵总和
之后就可以得到一个式子:
dp[i][j] = dp[i-1][j] + dp[i][j-1] +value[i][j] - dp[i-1][j-1] #就是将旁边两个矩阵相加然后减掉重复并加上本身
value[i][j]就是题目中给出矩阵的值
之后只要按行的顺序遍历,然后按列的顺序遍历就好了,记得保存最小的面积
n,m = map(int,input().split())
value = [[0] *m for i in range(n+1)]
dp = [[0] *m for i in range(n+1)]
sumvalue=0
for i in range(1,n+1):
value[i]= list(map(int,input().split()))
sumvalue+=sum(value[i])
answervalue = float("inf") #差值的最小值
answer = (0,0) #答案的值
answerarea = float("inf") #答案的面积
for i in range(1,n):
for j in range(1,m):
dp[i][j] = dp[i-1][j]+dp[i][j-1]-dp[i-1][j-1]+value[i][j] #动规方程
cha = abs(dp[i][j]-sumvalue)
if(cha<=answervalue):
if(cha==answervalue and i*j<answerarea):
answer=(i,j)
answerarea = i*j
else:
answer=(i,j)
answerarea = i*j
answervalue= cha
print(answer[0],answer[1])
第九题
问题描述
杂货铺老板一共有N件物品,每件物品具有ABC三种属性中的一种或多种。从杂货铺老板处购得一件物品需要支付相应的代价。
现在你需要计算出如何购买物品,可以使得ABC三种属性中的每一种都在至少一件购买的物品中出现,并且支付的总代价最小。
输入格式
输入第一行包含一个整数N。
以下N行,每行包含一个整数C和一个只包含"ABC"的字符串,代表购得该物品的代价和其具有的属性。
输出格式
输出一个整数,代表最小的代价。如果无论如何凑不齐ABC三种属性,输出-1。
样例输入
5
10 A
9 BC
11 CA
4 A
5 B
样例输出
13
数据规模和约定
对于50%的评测用例,1 <= N <= 20
对于所有评测用例,1 <= N <= 1000, 1 <= C <= 100000
思路
这道题的暴力方法可以通过全排列的方法,其实就是利用深搜来做,将所有可能性都遍历一遍,但是需要在找不到的时候及时重点,然后纪录下cost,当ABC都在字符串中就返回,但是如果不再就继续搜索下去
代码:
C = int(input())
string1 = ['' for i in range(C)]
value = [0 for i in range(C)]
for i in range(C):
temp = input().split() #使用了string
string1[i] = temp[1]
value[i] = int(temp[0])
def dfs(zifu,cost,index):
mincost = float('inf')
if('A' in zifu and 'B' in zifu and 'C' in zifu):
return cost
if(index>C): #如果找不到
return float('inf') #返回最大值
for i in range(index,C): #不一定全部选择
# print(''.join([zifu,string1[i]]),cost+value[i],i+1)
cost1 =dfs(''.join([zifu,string1[i]]),cost+value[i],i+1) #一定选择这个吗
if(cost1<mincost):
mincost=cost1
return mincost
mincost = dfs('',0,0) #dfs(string,cost,index) #从index
print(mincost) #
第十题
给定一个序列 (a_1, a_2, …, a_n), 它的一个上升子序列是指从序列中取出一些元素,按照原来的顺序排列后,是单调递增的序列。
例如,对于序列 (3, 2, 7, 6, 7),取出下标为 2, 4, 5 的元素 a_2, a_4, a_5,即 2, 6, 7,是一个上升子序列。
在这个序列中,有 7 个长度为 2 的上升子序列,例如
1. 下标 1, 3 对应的 3, 7;
2. 下标 1, 4 对应的 3, 6;
3. 下标 1, 5 对应的 3, 7;
4. 下标 2, 3 对应的 2, 7;
5. 下标 2, 4 对应的 2, 6;
6. 下标 2, 5 对应的 2, 7;
7. 下标 4, 5 对应的 6, 7。
注意,可能有下标不同但对应数值相同的上升子序列,他们应当算成不同的上升子序列。
给定序列,请问序列中一共有多少个长度为 k 的上升子序列。
输入格式
输入第一行包含两个整数 n, k,表示序列的长度和上升子序列的长度。
第二行包含 n 个整数 a_1, a_2, …, a_n,表示给定的序列。
输出格式
输出一行,包含一个整数,表示长度为 k 的上升子序列的数量,答案可能很大,请输出答案除以 1000007 的余数。
样例输入
5 2
3 2 7 6 7
样例输出
7
数据规模和约定
对于 30% 的评测用例,1 <= n <= 20, 0 <= a_i <= 100。
对于 50% 的评测用例,1 <= n <= 100, 0 <= a_i <= 1000。
对于所有评测用例,1 <= n <= 1000, 1 <= k <= 10, 0 <= a_i <= 10000。
思路
这道题主要是需要利用一个二维数组dp[i][j]纪录第i位之前的长度为j的递增数列的个数,这样可以得到动态规划方程,只需要将dp[i][j] 前i位的数遍历一遍,如果后面的数大于前面的数,就更新dp[i][j]
dp[i][j] = dp[x][j-1]+dp[i][j]
代码
n,k = map(int,input().split())
S = list(map(int,input().split()))
dp =[[0 for i in range(k+1)] for j in range(n+1)] #
for i in range(n):
dp[i][1] = 1 #将所有元素都有长度为1的递增序列
for i in range(n):
for j in range(i):
if(S[i]>S[j]):
for l in range(2,k+1): #也就是在k的
dp[i][l] = (dp[j][l-1]+dp[i][l]) % 1000007 #动规方程
maxvalue=0
for i in range(n):
maxvalue = (maxvalue+dp[i][k])%1000007 #相加所有位
print(maxvalue)