第一题

问题描述
请问在 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)