Algorithm practice -1
1、17的倍数
将正整数 m 和 n 之间(包括 m 和 n)能被 17 整除的数累加。其中,0 < m < n < 1000000000。
Input : 一行,包含两个整数m和n,其间,以一个空格间隔。
Output : 输出一行,包行一个整数,表示累加的结果。
Sample Input : 50 85
Sample Output : 204
三种做法,时间复杂度依次降低
1、取 i= m,从m到n 循环,i每次加1,遇到17的倍数便加和
2、取m 到n第一个17的倍数tmp,tmp逐次加17,求和
3、取m 到 n第一个17的倍数tmp1 = m * 17,最后一个17的倍数,tmp2 = n * 17,n到m 一共sn(利用求和公式)个17,求sn*17即可
''' python3'''
m,n = map(int,input().split())
a = m / 17
if a-int(a) == 0:
a = int(a)
else :
a = int(a)+1
b = n // 17
c = (b - a + 1)
sn = int (a*c + c*(c-1)/2)
print(sn*17)
2、空瓶换饮料
某饮料公司最近推出了一个“空瓶换饮料”的活动:如果你拥有3个空瓶就可以兑换一瓶饮料,初始你有 n 瓶饮料,喝完后的空瓶可以继续用来兑换饮料。问总共可以喝到多少瓶饮料。
Input : 一行,1个整数n,表示初始饮料的数量(1 <= n <= 109)。
Outout : 一行,对应答案
Sample Input : 10
Sample Output : 14
空瓶数大于等于3时进行循环,每次循环计算两个值:本次空瓶能换多少瓶饮料;剩下的空瓶以及兑换完饮料后的空瓶(使用python)
''' pyhton '''
n = int(input().split()[0])
num = n
while (n >= 3) :
num += n//3
n = n//3 + n%3
print(num)
3、水仙花数
水仙花数是指一个 n 位数,它的每位(个位、十位、百位…)上的数字的 n 次幂之和等于它本身。(例如:13 + 53 + 33 = 153)给出一个整数M,求 >= M的最小的水仙花数。
注:水仙花数根据Wiki的定义是一个N位非负整数,其各位数字的N次方和等于该数本身。因该定义源自外文定义,故以Wiki为准。
Input : 一个整数M(10 <= M <= 1000)
Output : 输出>= M的最小的水仙花数
Sample Input : 99
Sample Output : 153
将输入的数字转换为字符串,然后拆分成数组
''' python '''
a = int(input().split()[0])
while True :
li = list(str(a))
n = len(li)
num = 0
for i in range(n):
num += int(li[i])**n
if num == a :
break
else :
a += 1
print(a)
4、两个数的平方和
给出一个整数N,将N表示为2个整数i与j的平方之和(i <= j),如果有多种表示,按照i的递增序输出。例如:N = 130,130 = 32 +112 =72 +92(注:32 + 112 同112 + 32 算1种)
Input : 一个数N(1 <= N <= 109 )
Output : 共K行:每行2个数,i j,表示N = i2 + j2(0 <= i <= j)。 如果无法分解为2个数的平方和,则输出No Solution
Sample Input : 130
Sample Output :
3 11
7 9
i 最大值为 n的开方,此时 i == j
''' python '''
n = int(input().split()[0])
i = 0
j = n
k = int( n ** 0.5) + 1
count = 0
while (i <= k) & (i < j ) :
j = (n - i ** 2) ** 0.5
if (j - int(j) == 0) :
count += 1
print( str(i) + ' ' + str(int(j)))
i += 1
if (count == 0) :
print('No Solution')
4、区间xor(异或)
给出区间(a,b),b >= a,求a xor (a+1) xor (a+2)…xor b。
Input : 输入2个数:a b,中间用空格分隔(1 <= a <= b <= 109 )
Output : 输出一个答案
Sample Input : 3 8
Sample Output : 11
找规律,每四个数为一个规律,a为规律中的第一个数。若a为奇数,则第1、3个位置不变,若a为偶数,则第2、4个位置不变
''' python '''
a,b = map(int,input().split())
c = num = a
li = []
li.append(num)
for i in range(3):
num = num ^ (c+1)
li.append(num)
c += 1
index = (b - a) % 4
n = (b - a) // 4
if a % 2 == 1:
if (index + 1) % 2 == 1 :
print(li[index])
else :
print(li[index-1]^b)
else :
if (index + 1) % 2 == 0 :
print(li[index])
else :
print(li[index-1]^b)
5、数组中和等于K的数对
给出一个整数K和一个无序数组A,A的元素为N个互不相同的整数,找出数组A中所有和等于K的数对。例如K = 8,数组A:{-1,6,5,3,4,2,9,0,8},所有和等于8的数对包括(-1,9),(0,8),(2,6),(3,5)。
Input:第1行:用空格隔开的2个数,K N,N为A数组的长度。(2 <= N <= 50000,-109 <= K <= 109) 第2 - N + 1行:A数组的N个元素。(-109 <= Ai <= 109 )
Output : 第1 - M行:每行2个数,要求较小的数在前面,并且这M个数对按照较小的数升序排列。 如果不存在任何一组解则输出:No Solution
Sample Input:
8 9
-1
6
5
3
4
2
9
0
8
Sample Output:
-1 9
0 8
2 6
3 5
将数组排序,i从头开始遍历,j从尾开始遍历,若两个数和大于K,则j处值太大,j–,反之i处值太小,i++
k,n = map(int,input().split())
li = []
for i in range(n):
li.append(int(input().split()[0]))
li.sort()
flag = 0
i =0
j = n-1
while (i < j):
if li[i]+li[j] == k :
flag = 1
print(str(li[i]) + ' ' + str(li[j]))
i += 1
j -= 1
elif li[j] > k-li[i] :
j -= 1
else :
i += 1
if flag == 0:
print('No Solution')
6、最大公约数GCD
输入2个正整数A,B,求A与B的最大公约数。
Input : 2个数A,B,中间用空格隔开。(1<= A,B <= 109 )
Outpt : 输出A与B的最大公约数。
Sample Input : 30 105
Sample Output : 15
1、蛮力解决,从两个数中较小的数开始递减,两个数同时取模,结果都为0时便是最大公约数
2、辗转相除法(欧几里得算法):以除数和余数反复做除法运算,当余数为 0 时,取当前算式除数为最大公约数
a,b = map(int,input().split())
if a <= b :
min = a
max = b
else :
min = b
max = a
while min > 0 :
if max % min == 0 :
break
temp = min
min = max % temp
max = temp
if min > 0:
print(min)
7、最小公倍数LCM
输入2个正整数A,B,求A与B的最小公倍数。
Input : 2个数A,B,中间用空格隔开。(1<= A,B <= 109 )
Outpt : 输出A与B的最小公倍数。
Sample Input : 30 105
Sample Output : 210
a,b = map(int,input().split())
if a <= b :
minv = a
maxv = b
else :
minv = b
maxv = a
i = 1
num = maxv
while i <= minv :
num = maxv * i
if num % minv == 0:
break
i += 1
print(num)