试题B 寻找整数
很自然的想法就是缩小检索数的范围,观察可发现%11和%17的结果都为0,则数必定为11和17的最小公倍数的倍数,即n=k1117(其中k为自然数),但检索范围还是有点大。
这次我们可以针对k做文章,发现1117%3=1,而11172%3=2,则可以发现1117*(3k+2)都会满足%3=2,又因为%2=1,即n为奇数,因此k要为奇数。于是我们很自然的就想当k为多少时,满足1117(3k+2)%4=1,同理可以不断的进行下去……我们当然希望选取更少的数来判断,因此就需要扩大选取的步长,且最好选取质数(因为非质数有时k会重复)
#找质数的余数之间关系缩小数的范围 这里以%3余2为主体(即3k+2),然后依次循环13,23,37,43,47等缩小k的范围提高运行效率
tmp=[0,0] #记录缩小的范围(起始数和步长)
i=0
for k in range(1,1000000,2): #因为%2=1,所以不能为2的倍数,因此3k+2,k要为奇数
if 187*(3*k+2)%13==10:
tmp[i]=k
i+=1
if i==2:
i=0
break
for k in range(tmp[0],1000000,tmp[1]-tmp[0]):#根据上一步算出来的结果来调整相应的起始数和步长
if 187*(3*k+2)%29==16:
tmp[i]=k
i+=1
if i==2:
i=0
break
for k in range(tmp[0],10000000,tmp[1]-tmp[0]):
if 187*(3*k+2)%37==22:
tmp[i]=k
i+=1
if i==2:
i=0
break
for k in range(tmp[0],100000000,tmp[1]-tmp[0]):
if 187*(3*k+2)%41==1:
tmp[i]=k
i+=1
if i==2:
i=0
break
for k in range(tmp[0],1000000000,tmp[1]-tmp[0]):
if 187*(3*k+2)%47==5:
tmp[i]=k
i+=1
if i==2:
i=0
break
dp=[187*(3*k+2) for k in range(tmp[0],pow(10,14),tmp[1]-tmp[0])]
dic={2: 1, 3: 2, 4: 1, 5: 4, 6: 5, 7: 4, 8: 1, 9: 2, 10: 9, 11: 0,
12: 5, 13: 10, 14: 11, 15: 14, 16: 9, 17: 0, 18: 11, 19: 18,
20: 9, 21: 11, 22: 11, 23: 15, 24: 17, 25: 9, 26: 23, 27: 20,
28: 25, 29: 16, 30: 29, 31: 27, 32: 25, 33: 11, 34: 17, 35: 4,
36: 29, 37: 22, 38: 37, 39: 23, 40: 9, 41: 1, 42: 11, 43: 11,
44: 33, 45: 29, 46: 15, 47: 5, 48: 41, 49: 46}
for n in dp:
for i in range(2,50):
if n%i!=dic[i]:
break
else:
print(n)
break
答案
2022040920220409
试题C
判断素数
def zhi(n):
num=0
for i in range(2,int(n**0.5)+1):
if(n%i==0):
return False
return True
代码:
但是没有平台测评过
import math
def zhi(n):
num=0
for i in range(2,int(n**0.5)+1):
if(n%i==0):
return False
return True
n=int(input())
k=0
for i in range(2,n//2):
if(zhi(i) and n%i==0):
k+=1
print(k)
试题D 矩形拼接
矩形的拼接一共有3种情况
分别是: 4,6,8
4就是刚好能合起来
6就是有一个小一点,凹进去了
8就是都合不上
**
4:
情况一:三个矩形中 ,各存在一条边xi(i=1,2,3) ,使得x1=x2=x3
情况二:三个矩形中存在两个矩形1,2 ,各存在一条边相等x1=x2,这两个矩形的另外一条边相加y1+y2和=最后一个矩形的其中一条边 x3(y3) 。
**
三个矩形中存在两个矩形1,2,这两个矩形的另外一条边相加y1+y2和=最后一个矩形的其中一条边x3(y3)。
def check4(x1,x2,x3,a):# 有保证一边等于另外两边之和,但是要排除总共是4条边的情况
if x1==x2+x3 and a[2]+a[3]-x2==a[4]+a[5]-x3:
return True #此时只有4条边,因为另外两条边相等
if x2==x1+x3 and a[0]+a[1]-x1==a[4]+a[5]-x3:
return True
if x3== x2+x1 and a[0]+a[1]-x1==a[2]+a[3]-x2:
return True
return False
def check6(x1,x2,x3):
if x1==x2+x3 or x2==x1+x3 or x3==x1+x2:
return True
return False
if __name__=='__main__':
N=int(input())
for n in range(N):
edge=8
a=list(map(int , input().strip().split()))
for i in range(0,2):
for j in range(2,4):
for k in range(4,6):
x1,x2,x3=a[i],a[j],a[k]
if x1==x2 and x2==x3: #有三条边相等
edge=min(edge,4)
if check4(x1,x2,x3,a): #总共有4条边的情况
edge=min(edge,4)
if x1==x2 or x2==x3 or x1==x3:
edge=min(edge,6)
if check6(x1,x2,x3):
edge=min(edge,6)
print(edge)
"""
2
2 3 4 1 2 4
1 2 3 4 5 6
"""
试题E 消除游戏(还是模拟解决)
思路
一次判断全部的边缘字母,记录下标,然后一次性把所有的字母pop()出去, 再根据新的列表来判断。
以下是只能通过7个测试用例的代码, 还有5个运行超时
n=list(input()) # 把所有的字母单独分析
num=0
while num<2**65:
clear1=[] # 记录边缘下标
l=len(n)
for i in range(len(n)):
if(i-1>=0 and i+1<len(n)):
if(n[i-1]==n[i] and n[i]!=n[i+1]):
clear1.append(i)
clear1.append(i+1)
if(n[i-1]!=n[i] and n[i]==n[i+1]):
clear1.append(i-1)
clear1.append(i)
num+=1;
clear1=list(set(clear1))
clear1=sorted(clear1, reverse=True)
for j in clear1:
n.pop(j)
if(l==len(n)):
break;
if(len(n)==0):
print("EMPTY")
else:
for i in range(len(n)):
print(n[i],end="")
试题F 重新排序
(差分的思想)
差分其实就是数据之间的差,什么数据的差呢?就是上面所给的原始数组的相邻元素之间的差值,我们令 d[i]=a[i+1]-a[i],一遍for循环即可将差分数组求出来。
下面给你一个栗子,给出一个差分数组先
差分数组怎么求
其实差分数组是一个辅助数组,从侧面来表示给定某一数组的变化,一般用来对数组进行区间修改的操作
还是上面那个表里的栗子,我们需要进行以下操作:
1、将区间【1,4】的数值全部加上3
2、将区间【3,5】的数值全部减去5
很简单对吧,你可以进行枚举。但是如果给你的数据量是1e5,操作量1e5,限时1000ms你暴力枚举能莽的过去吗?T到你怀疑人生直接。这时我们就需要使用到差分数组了。
其实当你将原始数组中元素同时加上或者减掉某个数,那么他们的差分数组其实是不会变化的。
利用这个思想,咱们将区间缩小,缩小的例子中的区间 【1,4】吧这是你会发现只有 d[1]和d[5]发生了变化,而d[2],d[3],d[4]却保持着原样。
发现是头和尾发生了改变,其中区间头+该数字,区间尾-该数字,然后用差分的公式,就能把所有的区间都算出来啦。
a[i]=a[i-1]+d[i]
应用差分的思想,就可以让时间复杂度降低了。
import sys
n= int(input())
a=[0]*1000005
a[1:n+1]=list(map(int,input().split(' ')))
m=int(input())
s=[0]*1000001 # 差分数组
u=[0]*(n+1)
yuan=0
for i in range(m):
w=input().split()
s[int(w[0])]+=1
s[int(w[1])+1]-=1
for i in range(1,n+1):
u[i]=u[i-1]+s[i]
for i in range(1,n+1):
yuan+=a[i]*u[i]
u[1:n+1]=sorted(u[1:n+1])
a[1:n+1]=sorted(a[1:n+1])
now=0
for i in range(1,n+1):
now+=a[i]*u[i]
print(now-yuan)
试题G: 全排列的价值
问题描述
对于一个排列 A=(a1,a2,⋯,an), 定义价值 ci 为 a1 至 ai−1 中小于 ai 的数 的个数, 即 。
ci=∣{aj∣j<i,aj<ai}∣。
定义 A 的价值为 ∑i=1nci 。
给定 n, 求 1 至 n 的全排列中所有排列的价值之和。
输入格式
输入一行包含一个整数 n 。
输出格式
输出一行包含一个整数表示答案, 由于所有排列的价值之和可能很大, 请 输出这个数除以 998244353 的余数。
样例输入 1
3