先看一个题目:
题面描述
小明很喜欢学数学,并且喜欢做一些奇怪的题,这天他想知道对于给定的 N ,有多少个 M 满足“ M<=N, gcd(N,M)==1, M 是偶数”。请你编写程序帮助小明解决这个问题。
输入数据
输入数据第一行为一个正整数 T ,表示测试数据的组数。 接下来的 T 组测试数据中, 每组测试数据为一行,包含一个整数 N (1≤T≤100, 1≤N≤10000 )。
输出数据
对于每一组输入数据,在单独的一行中输出 ”Case #id: M”, 表示第 id 组数据结果是 M , id 从 1 开始;
样例输入
小明很喜欢学数学,并且喜欢做一些奇怪的题,这天他想知道对于给定的 N ,有多少个 M 满足“ M<=N, gcd(N,M)==1, M 是偶数”。请你编写程序帮助小明解决这个问题。
输入数据
输入数据第一行为一个正整数 T ,表示测试数据的组数。 接下来的 T 组测试数据中, 每组测试数据为一行,包含一个整数 N (1≤T≤100, 1≤N≤10000 )。
输出数据
对于每一组输入数据,在单独的一行中输出 ”Case #id: M”, 表示第 id 组数据结果是 M , id 从 1 开始;
样例输入
4
1
2
11
23
1
2
11
23
样例输出
Case #1: 0
Case #2: 0
Case #3: 5
Case #4: 11
Case #2: 0
Case #3: 5
Case #4: 11
Hint:
gcd(a,b)==1 表示 a 与 b 的最大公约数为 1 ,即 a 与 b 互素。
gcd(a,b)==1 表示 a 与 b 的最大公约数为 1 ,即 a 与 b 互素。
- 讲讲算法思路
- 分析输入输出与显示
- 源代码与递归函数的精华所在
1.两个数互素:最小公约数为1。我们只要把大一点的数%较小的数,上一轮较小的数%这个余数又得到一个余数,每次判断这个余数是0还是1。只要有0出现就不互素。
2.输入用list[]保存。输出的序号可以在循环里面计数。输出赋值:print('Case #%d: %d'%(x,y))
3.#求法,可能会用到函数,递归函数等 def gcd(x,y):#定义递归函数 if x>=y: z1=x%y#取余数 if z1==0:#如果余数==0,立马返回0这个指示表示x,y这两个数不是互素。 return 0 elif z1==1:#如果余数==1,立马返回1这个指示表示x,y这两个数是互素。 return 1 else:#如果上述的情况都不满足,立马递归,用结果作为输入,再次计算,直到返回值是0/1 return gcd(y,z1) else: (x,y)=(y,x) z1=x%y if z1==0: return 0 elif z1==1: return 1 else: return gcd(y,z1) test_nums=int(input()) stores=[] for ii in range(test_nums): stores.append(int(input())) m=0#计数 for i in stores: n=0 m=m+1 for M in range(2,i+1,2): if_is=gcd(i,M) if if_is==1: n=n+1 print('Case #%d:'%(m),n)这里的递归函数其实写的还是比较保守的,
def get_gcd(a,b): if(a % b) == 0: return b else: return get_gcd(b, a % b)这是某位同学的改进,直接判断递归函数的结果是不是1,是1的话就是互素。这里因为递归,所以就算较小数%较大数也不会有关系,无非就是在递归一次。
>>> 10%3 1 >>> 3%10 3 >>> 10%3 1递归函数的特点:定义的函数里一定要在return后面再次调用原函数,并且有if函数的return某一个计算的变量作为最后的结果。不然就没完没了了。
文章来源: Python递归函数的正确理解与使用