算法竞赛入门经典:第6章例题
来源:互联网 发布:html css js源码下载 编辑:程序博客网 时间:2024/06/03 21:46
例题1:模拟并行程序的运行,采取双端队列来运行。主要考虑到以下几个逻辑问题:
(1) 首先要注意当前剩下的时间是不是还够运行该条命令。不够的话就要结束当前的循环且不能删除该条命令。即便是end命令可能也不够时间完成!
(2) 如果该程序是正常结束,就不要将该命令入队列,或者如果该命令是因为被锁住而退出循环,也不能入队列。注意不能用剩余时间来判断,因为有可能使执行lock命令之后时间刚好为0,然后才被退出循环的。如果一定要用剩余时间来判断,就应该将这个减去剩余时间的执行放在if分支的最后执行。
(3) 注意执行完unlock以后要把阻止队列的任务放出来
def empty(q): return len(q)==0def get_from_print(code): cmd = code.split(' ') return Value[cmd[1]]def get_var(code): cmd = code.split(' ') return cmd[0],cmd[2]def Type(code): if code=='lock':return 0 elif code=='unlock':return 1 elif code[0:3]=='end':return 2 elif code[0:5]=='print':return 3 else:return 4def process(n,t,Q): print(t) programs_left = n index = 1 while programs_left != 0: line = input() if line[0:3]=='end':p[index].append(line);index+=1;p[index] = [];programs_left-=1;continue p[index].append(line)#put the input into the p[index] for i in range(n):waitque.append(i+1) islocked = False while not empty(waitque): program = waitque.popleft() remainder = Q blocked = False while remainder > 0: code = p[program][0] code_type = Type(code) #print('case:',program,'codetype******',code_type,code) if code_type == 0:#.....................lock if remainder>= t[code_type]:remainder -= t[code_type] else:break# no enough time to run the cmd if not islocked: islocked = True else: blocked = True blockque.append(program)#put program into the blockque break#.........................would not delete the code beacuse it failed elif code_type == 1 :#..................unlock if remainder>= t[code_type]:remainder -= t[code_type] else:break# no enough time to run the cmd islocked = False if not empty(blockque): another_program = blockque.popleft() waitque.appendleft(another_program)#put another_program into the first of waitque elif code_type == 2:#...................end if remainder>= t[code_type]:remainder -= t[code_type] else:break# no enough time to run the cmd remainder = 0 elif code_type == 3:#.......................print if remainder>= t[code_type]:remainder -= t[code_type] else:break# no enough time to run the cmd var = get_from_print(code) print(program,':',var)#output program,the value of var else :#.....................................assignment if remainder>= t[code_type]:remainder -= t[code_type] else:break# no enough time to run the cmd var,constant = get_var(code) Value[var] = constant p[program].remove(code)#delte the code which has been run if not empty(p[program]) and not blocked: waitque.append(program)#put program into the end of waitquedef get_args(): line = input() line = line.split(' ') n,t1,t2,t3,t4,t5,Q = line n,t,Q = int(n),[int(t1),int(t2),int(t3),int(t4),int(t5)],int(Q) return [n,t,Q]process(*get_args())
例题6−2 :典型的栈的运用,从出去的顺序入手,对于每一个元素,都将所有比它小的元素入一个新的栈,假如发现一个入栈的结果不等于当前的目标同样位置的元素,则不可以。
def test(enter,depart): i,k,n = 1,0,len(depart) new = [] while k<n: new_items = 1 new.append(depart[k]) while i<n: if i==depart[k]:i+=1;break new.append(i)#push i into new if new[i]!=depart[i]:return False i+=1 new_items += 1 k+= new_items return Trueprint(test([1,2,3,4,5],[5,4,1,2,3]))
例题6−3 :利用栈来求表达式,矩阵链乘
def matrix(expression): def times(a,b): return a[0]*b[0]*b[1] def mul(a,b): return (a[0],b[1]) def ok(a,b): return a[1]==b[0] sum,s=0,[] for each in expression: if each.isalpha():s.append(record[each]);print(each,s) elif each==')': b = s.pop() a = s.pop() if ok(a,b):s.append(mul(a,b));sum+=times(a,b);print(s,times(a,b)) else:return 'error' if len(s)!=1: sum += times(s[1],s[0]) return sumrecord = {}def process(): n = int(input()) while n>0: line = input() line = line.split(' ') record[line[0]] = (int(line[1]),int(line[2])) n-=1 while 1: exp = input() if exp=='':break print(matrix(exp))process()
例题6−4 悲剧的键盘,这个题目的关键是不能用数组插入,因为插入会引起大量的移动最终导致超时。方法是利用链表来解决问题,这里的链表不是实际意义的链表,只是利用数组模拟的链表。构造一个next数组,其中next[i]代表字符i右边是哪个字符!为了方便起见,虚拟一个next[0]代表最左边的字符,用一个last来标志当前的最后一个字符的位置,curr代表当前光标的位置(也是要插入的位置)。
def proc2(): line = ' '+input() while line!='': curr,last=0,0 next = [0]*(len(line)+5) for i,ch in enumerate(line): if ch=='[':curr=0 elif ch==']':curr=last else:#simulate the insert operation next[i] = next[curr] next[curr] = i if curr==last:last=i#update the last curr = i i = next[0] print(next) while i!=0: print(line[i],end='') i = next[i] print() line = input()proc2()
6−5 这道题目有点难度,主要是调试起来很麻烦,根据答案进行了一定优化,得到下面代码.
(a): 注意采取了双向链式的结构
(b): 一定要区分交换节点这个操作如果两节点相邻要特殊对待,同时相邻的方式不同,处理方式不同。在这里采取只处理一种相邻的方式,另一种可以通过交换x,y转化。
(c): 注意采取了特殊的方式来处理反转这个操作,因为这个操作很消耗时间,用一个标记来处理而不真正执行。但是要注意 1,x,y在逆转状态下变成了2,x,y,这招略trick。
(d): 构造辅助函数link(x,y),减少代码量。注意到,其实删除一个节点等价于link(p_x,n_x)。想到这一点就容易减少代码
def Get(cmd): cmd = cmd.split(' ') if len(cmd)==3: return int(cmd[0]),int(cmd[1]),int(cmd[2]) else: return 4,None,Nonedef proc(n,cmds): next =[i+1 for i in range(n+5)] pre = [i-1 for i in range(n+5)] rev = 0 def link(L,R): next[L],pre[R] = R,L for cmd in cmds: Type,x,y = Get(cmd) if rev==1 and Type<2:Type = 3-Type if Type==3 and next[y]==x:x,y = y,x if x and y:p_x,p_y,n_x,n_y = pre[x],pre[y],next[x],next[y] if Type == 2:#right if not next[y]==x:#x is not in the right of y:, link(p_x,n_x);link(y,x);link(x,n_y) elif Type == 1:#left if not next[x]==y: link(p_y,x);link(x,y);link(p_x,n_x) elif Type == 3: if not next[x]==y: link(p_x,y);link(y,n_x);link(p_y,x);link(x,n_y) else: link(p_x,y);link(y,x);link(x,n_y) else:#reverse all the list rev = 1 sum,i,first = 0,1,next[0] while i<=n: if (n-i+1 if rev else i)%2==1:sum+=first first,i= next[first],i+1 print(sum)def func(): line = input() while line!='': cmds = [] line = line.split(' ') n,num = int(line[0]),int(line[1]) line while num: cmd = input() cmds.append(cmd) num-=1 proc(n,cmds) line = input()func()
0 0
- 算法竞赛入门经典:第6章例题
- 算法竞赛入门经典第6章例题(2):二叉树部分+四分树
- 【算法竞赛入门经典】6.2链表 例题6-4 UVa11988
- 算法竞赛入门经典第四章例题总结:
- 算法竞赛入门经典 例题9-1
- 算法竞赛入门经典 例题8-1
- 算法竞赛入门经典 例题 9-4
- 算法竞赛入门经典例题-勇者斗恶龙
- 算法竞赛入门经典例题-蚂蚁
- 算法入门经典2 第6章例题
- 算法竞赛入门经典第3章
- 【索引】算法竞赛入门经典-第6章 数据结构基础
- 算法竞赛入门经典第6章:图论基础
- 算法竞赛入门经典(第二版)-刘汝佳-第七章 暴力求解法 例题(6/15)
- 算法竞赛入门经典(第2版)例题4-6 师兄帮帮忙 (A Typical Homework UVa 12412)
- 算法竞赛入门经典(第2版)-刘汝佳-第八章例题解题源码(C++语言)(部分)
- 算法竞赛入门经典(第2版)-刘汝佳-第九、十一章例题解题源码(C++语言)(部分)
- [算法]算法竞赛入门经典第4章笔记
- js内存泄漏
- Em13c不能安装在RHEL6.8上,原因是没有通过认证
- lxml学习 - 安装
- 自定义ViewGroup——实战,实现FlowLayout
- Long Names Are Long
- 算法竞赛入门经典:第6章例题
- [阶段一]Java面向对象(4)
- CSS3新属性
- 【c++程序】全局变量和局部变量汇总
- windows编程之动态链接库的使用
- 大话设计模式———c++反射机制实现
- mssql 按月统计,按日统计,按周统计,按季度统计
- 图像的基本函数运算
- Linux学习之路