算法竞赛入门经典第三章总结(python实现)
来源:互联网 发布:java 算法 快速排序 编辑:程序博客网 时间:2024/05/22 17:47
#开灯问题def N_lamps(n,k): L = [0]*(n+1) for i in range(1,k+1): factor = 1 while(factor*i<=n): L[factor*i] = 1-L[factor*i]#1代表开 factor += 1 for k,i in enumerate (L): if(i==1):print(k,' ',end = '') ###没啥好说的,简单的模拟 #蛇形矩阵def snake_matrix(n): L = [[0]*n for i in range(n)] dir = [(1,0),(0,-1),(-1,0),(0,1)] i = 0;j = n-1;x = 1; L[i][j] = 1;#先初始化第一个位置 while(x<n*n): while(i<n-1 and (L[i+1][j]==0)): L[i+1][j] = x+1;x+=1;i+=1 while(j>0 and (L[i][j-1]==0)): L[i][j-1] = x+1;x+=1;j-=1 while(i>0 and (L[i-1][j]==0)): L[i-1][j] = x+1;x+=1;i-=1 while(j<n-1 and (L[i][j+1]==0)): L[i][j+1] = x+1;x+=1;j+=1 for row in L: print(row)###本题有两种思路,但是一个是跟着填入的数字走,根据当前坐标判断下一个数字应填在哪里,另一种思路就是跟着轨迹走,下,左,上,右不断循环.第一种方法相对麻烦(我就采取的第一种~~~~),因此给出了第二种的python实现. ###竖式问题,给定一个数字集合,找出所有形如abc*de的竖式算式,并且保证完整的竖式所有数字都是属于该集合。输出所有的竖式和解的行数。代码如下:number = 0def vertical_form_de(abc,data): def test(buf,data): for each in buf: if(int(each) not in data):return False return True global number for d in data: for e in data: de = d*10+e x = abc*d;y = abc*e;z = abc*de buf = str(x)+str(y)+str(z) if(test(buf,data)): number+=1; print('%5d\nX%4d\n-------\n%5d\n%4d\n------\n%5d\n'%(abc,de,x,y,z))def vertical_form_abc(data): for a in data: for b in data: for c in data: vertical_form_de(a*100+b*10+c,data) print('The number of solutions = %d'%number)###书上给出的解法太暴力了,我的思路是从给定的集合里面来遍历.需要注意下输出格式,利用%5d,%4d来控制格式.def toTex(buf): left_right = 0#0代表左,1代表右 new_buf = '' for each in buf: if(each == '"'): if(left_right == 0):each = '“' else: each = '"' left_right = 1 - left_right new_buf+=each print(new_buf)#toTex('" To be or bot to be," quoth the Brad,"that is the question".')#字符错位问题####这题也很简单,关键是用好一个数组,一开始我想用map来解,但是这有些自找麻烦。。。。还是这个策略更容易实现.这也提醒我们使用map前要考虑有没有更简单的对应关系.def WERTYU(buf): s = '`1234567890-=QWERTYUIOP[]\\ASDFGHJKL;ZXCVBNM,./' for char in buf: try: pos = s.index(char) except: pos = -1 if(pos!=-1):print(s[pos-1],end = '') else:print(char,end = '')#WERTYU('O S, GOMR YPFSU/')def palindromes(buf): s = 'A 3 HIL JM O 2TUVWXY51SE Z 8 ' msg = ['is not a pal','is a regular pal','is a mirrored string','is a mirrored pal'] def rev(ch): if(ch.isalpha()):return s[ord(ch)-ord('A')] else :return s[ord(ch)-ord('0')+25] print(buf,buf[::-1]) p = 1 if (buf[::-1]==buf) else 0#回文 old_buf = list(buf) buf = list(map(rev,buf)) m = 1 if (buf[::-1]==old_buf) else 0 print(m,p,buf,old_buf) print (msg[2*m+p])#palindromes('NOTAPALINDROME')#palindromes('2A3MEAS')#palindromes('ATOYOTA')###方法是采取一个数组来进行映射,注意几点:首先reverse会改变自己所绑定的值,因此较好的办法是采取[::-1]的切片,对于str和list都是通用的.另外四种情况的组合最后是采取一个类似二进制的表达来输出的.msg的作用很有意思.def master_mind(ans,guess):#test从guess本身考虑问题 def test(each): tot = 0 wrong_occur = 0 mark = [0]*len(each) for index in range(len(each)): if(ans[index] == each[index]):tot+=1;mark[index]=1; for index in range(0,len(each)): if(mark[index]!=1): pos = -1 while(True): try: pos = ans.index(each[index],pos+1) if(mark[pos]!=1):wrong_occur += 1;break; except:break return tot,wrong_occur#test1从1-9数字的角度考虑问题 def test1(each): A = 0;B = 0; for index in range(len(each)): if(ans[index] == each[index]):A+=1; for d in range(1,10): c1 = 0;c2 = 0; for index in range(len(each)): if(ans[index]==d):c1+=1; if(each[index]==d):c2+=1; B += min(c1,c2); return (A,B-A) for each in guess: print(test(each))###其实这个问题书本上的解法很有意思,值得思考,我给出的解法需要多用一个数组作为标志数组,算法复杂度是O(n^2),首先求解出A并且做好标记,然后对guess序列的每一个数进行在ans中的查找,直到有一个位置的数字被找到且没有被标记过. ###而书本的答案则只需要O(n*m)的复杂度,其中m是代表可能出现的数字集合的长度. ###书本的答案采取的办法是统计每一个数字在ans和guess序列出现的次数,然后取两者中的最小值,这代表它们对B做出的贡献,然后不断累加即可.最后注意要减去A,因为不能计算已经正确包含的值.def mysum(x): sum = x while(x>0): sum += x%10 x //= 10 return sumdef min_generator(n): m = len(str(n))#获取n的位数 for x in range(n-9*m,n):#n-9m -> n-1 if(mysum(x)==n):print(x);return print(0)#min_generator(121)#mysum(5555)def less(a,b): a_l = len(a);b_l = len(b) if(a_l > b_l): return less(b,a) n = a_l if a_l < b_l else b_l for i in range(n): if(a[i]<b[i]):return True#小于 elif(a[i]>b[i]):return False#大于 if(b_l == a_l):return False#相等 else: return True#小于###这个题目不难,但是书上给出的答案有点意思,居然是空间换时间的做法,这个角度值得思考.但是还是有其他办法的,可以很容易的缩小枚举的范围是n-9m到n,m是n的位数.def circular_s(s): temp = s for i in range(len(s)): if(less(temp,s)):ans = temp temp = temp[1:]+temp[0] print(ans)#circular_s('CGAGTCAGCT')def score(buf):#统计连续出现的O curr_num = 0;tot = 0 for ch in buf: if(ch=='O'):curr_num+=1; else: curr_num = 0 tot += curr_num print(tot)#score('OOXXOXXOOO')def Molar_Mass(buf): weight = {'C':12.01,'H':1.008,'O':16.00,'N':14.01} sum = 0.0;i = 0 length = len(buf) while(i+1<length): if (buf[i+1].isdigit()):sum += weight[buf[i]]*int(buf[i+1]);i+=2 else: sum += weight[buf[i]];i+=1; if(i==length-1):sum+= weight[buf[i]] print(sum)#Molar_Mass('C6H5OH2')###唯一需要注意的是最后一个分子def get_zero(i,num): tot = 0 u = 1; for j in range(1,i+1): x = j*u; tot += x u *= 10; tot*=9 return tot - num*9def digit_count(n): k = 0;i = 0; while(True): if((k*10+9) <= n):k = k*10+9;i+=1; else:break gap = n - k sum = [i*(k+1)//10]*10; sum[0] = get_zero(i,sum[1]) for digit in range(k+1,n+1): for ch in str(digit): sum[ord(ch)-ord('0')]+=1 print(sum)#digit_count(5000)####这个题目暴力解就太简单了,这里稍微用了一点数学的知识: ####我们首先看一看1-999的出现情况,首先假设数字出现的规律是001-999,这样因为每一位都是平均分配的,所以每一位出现的次数是3*1000/10 = 300def perodic(buf): def test(s): k = len(s) for i in range(len(buf)//k): if(s!=buf[i*k:(i+1)*k]): return False return True beg = '';end = '' length = len(buf) for i in range(length//2 + 1): beg += buf[i] end = buf[length-i-1]+end if(beg == end and test(beg)):print(len(beg));return print(len(buf))#perodic('abccbaabccxba') ###这里的算法复杂度是n^2,先从两头开始比较,最坏情况下比较的次数是1+2+3+....(n/2) = n^2/8,然后进行检验,检验的比较次数是n. ###如果采取最直接的暴力比较法,最坏情况下的比较次数是(n/2)*n = n^2/2,显然上面的算法要好一些.但是还是不能降低复杂度的量级.... #空格迷题def get_pos(matrix): for i,k in enumerate(matrix): for j,item in enumerate(k): if(item == ' '):return[i,j]def Puzzle(matrix,command): empty_pos = get_pos(matrix) dir = {'A':[-1,0],'B':[1,0],'L':[0,-1],'R':[0,1]} def move(instruction): nonlocal empty_pos#声明它不是move的局部变量 old_i = empty_pos[0] old_j = empty_pos[1] if(instruction not in dir):return False i = old_i + dir[instruction][0] j = old_j + dir[instruction][1] if(i<5 and i >0 and j<5 and j>0 ): matrix[old_i][old_j],matrix[i][j] = matrix[i][j],matrix[old_i][old_j]#交换两个元素 empty_pos = [i,j] return True else:return False for ins in command: if(not move(ins)):print('This puzzle has no final configuration');return for i in matrix: print(i)A = [['T','R','G','S','J'],['X','D','O','K','I'],['M',' ','V','L','N'],['W','P','A','B','E'],['U','Q','H','C','F']]Puzzle(A,'ARR')
简单的模拟而已,需要注意的是python3 nonlocal的用法可以用来修改外部的自由变量.
0 0
- 算法竞赛入门经典第三章总结(python实现)
- 算法竞赛入门经典 第三章
- 算法竞赛入门经典第三章笔记
- 算法竞赛入门经典-第三章源代码
- 算法竞赛入门经典第三章
- 算法竞赛入门经典第三章
- 算法竞赛经典入门第三章习题
- 算法竞赛入门经典(第三章)
- 算法竞赛入门经典第三章
- 《算法竞赛入门经典》第三章思考题
- 算法竞赛入门经典习题 第三章
- 算法竞赛入门经典(1,2章的python实现)
- 算法竞赛入门经典 第八章总结
- 《算法竞赛入门经典》第四章总结
- 算法竞赛入门经典第三章总结(2):后半部分习题解答
- 算法竞赛入门经典第三章习题总结(记录向)
- 《算法竞赛入门经典》第三章习题3-2
- 《算法竞赛入门经典》第三章习题3-1
- 漫画城之自动轮播+GridView
- zabbix3.0 从坚持到用起 开始配置管理界面
- [1]Matlab如何创建文件夹
- Atom, Xcode, VisualStudio等编辑器activate-power-mode离子抖动炫酷效果插件安装(Mac)
- iOS开发小技巧[004]:千辛万苦找不到解决方案,那是因为你不会用Xcode的帮助文档
- 算法竞赛入门经典第三章总结(python实现)
- MySQL数据库远程备份
- EL表达式
- 巴什博奕(Bash Game)
- 三色旗算法(C描述)
- FileChannel
- git
- iOS利用dSYM文件解析crash日志
- 【AR】移动应用中的AR开发,5款最受欢迎工具推荐!