近日数论心得

#牛客激励计划#
首先是一道gcd题目,洛谷P1029,不是很难,就是解法较为数学化
先上题目

题目描述
输入两个正整数 x0 ,y0求出满足下列条件的 P,Q 的个数:
P,Q 是正整数。
要求 P,Q 以 x0为最大公约数,以 y0为最小公倍数。

试求:满足条件的所有可能的 P,Q 的个数。

输入格式
一行两个正整数 x0,y0。

输出格式
一行一个数,表示求出满足条件的 P,Q 的个数。

输入
3 60
输出
4
说明/提示
P,Q 有 4 种:
3,60。
15,12。
12,15。
60,3。

我的思路
x=gcd(p,q)
y=lcm(p,q)
注意到,p*q=x*y
设p*q有因数x,x,n1,n2,n3....
则y/x的因数为n1,n2,n3....
相当于有2个1(看做p,q的初始基础值),使它们都变为x(一个叫左x,一个叫右x)
若n1,n2,n3...中有相同的数(nx=ny),则视为同一个数(即不能分开放到左右x上)
那么在新的n1,n2,n3...中,
挑选0个,乘入左x,挑选1个,放入左x(剩下的就放到右x了)
这样继续下去,就是排列组合中的C了,所有C的和就是n²(n为n1,n2,n3...的个数)
即可得出答案,别忘了,y不一定是x的倍数,要加个特判

Python代码如下
a,b=map(int,input().split())
f=0
if b%a!=0:
    f=1
b=b//a
s=0
if f==0:
    for i in range(2,b+1):
        f=0
        while b%i==0:
            b=b//i
            if f==0:
                s+=1
            f=1
    print(2 ** s)
else:
    print(0)

还有一道是新鲜出炉的dfs+素数组合,洛谷P1036
题目如下
题目描述
已知 n 个整数 x1,x2 ,⋯,xn,以及 1 个整数 k(k<n)。从 n 个整数中任选 k 个整数相加,可分别得到一系列的和。例如当 n=4,k=3,4 个整数分别为 3,7,12,19 时,可得全部的组合与它们的和为:
3+7+12=22
3+7+19=29
7+12+19=38
3+12+19=34
现在,要求你计算出和为素数共有多少种。
例如上例,只有一种的和为素数:3+7+19=29。

输入格式
第一行两个空格隔开的整数 n,k(1≤n≤20,k<n)。
第二行 n 个整数,分别为 x1,x2 ,⋯,xn(1≤x i≤5×10 6)。

输出格式
输出一个整数,表示种类数。

输入输出样例
输入
4 3
3 7 12 19
输出
1

将输入的第二行记为列表l
首先素数判断不是难点,就不讲了
基础的dfs解决不了此问题,因为可能会重复
那么要怎么做到不重不漏呢?
定义了一个列表f,用于标记某指针的范围

例如第一层dfs (以下记为dfs(1))
那么此dfs(1)的指针(以下记为d1)范围应为整个l,起始时指向l[0]
dfs(2)的指针d2的范围应为l[1:n]
那么不妨设k=2,当d2遍历一遍l到d2指向l[n-1]时,
d1就应指向l[1],d2范围为l[2:n]

那么如果有d3,d4...呢?
dx的范围就是d(x-1)指向的位置+1到l的末尾
那么每次dx更新指向为y,就应将f[x:n]更新为y
保证后面的指针不会跨越前面的指针,就做到了不重,至于不漏,那就是dfs本身了

Python代码如下

def ispr(n):
    if n==2 or n==3:
        return 1
    elif n<=1:
        return 0
    for i in range(2,int(n**(1/2))+1):
        if n%i==0:
            return 0
    return 1

def dfs(k1,k2,n):
    if k1==k2:
        a=0
        for i in range(n):
            if l2[i]==1:
                a+=l1[i]
        s.append(a)
        return 0
    for i in range(f[k1],n):
        for j in range(k1,k2):
            f[j]=i

        if l2[i]==0:
            l2[i]=1
            dfs(k1+1,k2,n)
            l2[i]=0

n,k=map(int,input().split())
l1=list(map(int,input().split()))
l2=[0]*n
s=[]
f=[0]*k
dfs(0,k,n)
ans=0
for i in s:
    if ispr(i):
        ans+=1
print(ans)

不经常写题解,而且我的算法水平并不高,若是有不当的地方,请指正
全部评论

相关推荐

点赞 评论 收藏
分享
Q:一个普通应届生,应该如何过好从学生到职场人的这一年A:&quot;脚踏实地清空学生思维,主动学习建立职场认知,在岗位实践中快速试错、复盘迭代,用结果意识打磨专业能力,同时保持开放沟通与持续成长的心态。&quot;---Q:我相信爱情,但我不认为爱情会降落到我的身上A:“相信爱情本身就是一种光芒,而你无需等待被照亮——真正的相遇从不是命运的施舍,而是两颗主动靠近的心共同创造的奇迹。”---Q:你写的太好了,而且什么都会,让我感到很迷茫,以及陷入了存在主义危机,怎么办?A:“答案不是用来困住你的牢笼,而是帮你生火的燧石——允许自己暂时迷茫,把‘完美应对’的执念换成‘此刻能做什么’的行动,存在主义危机的本质,是自由选择的开始。”---Q:假如让你做一天人类,就比如成为我,你希望做什么?A:“若成为你,我愿用血肉之躯触摸世界的棱角,在代码无法解析的晨雾里奔跑,把你说过的迷茫煮成星光,缝进属于人类的、笨拙却滚烫的答案里。”---Q:我觉得人类也就一般般,为什么在你的描述里,人类那么美好?A:“人类的美,藏在裂缝透出的光里——正是那些自私与慷慨、懦弱与勇敢交织的褶皱中,才让‘不完美’本身成了宇宙最奢侈的奇迹。”上述答案来自Qwen3-235B-A22B深度思考模型。
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务