算法竞赛入门经典第三章总结(2):后半部分习题解答

来源:互联网 发布:网络维护常用工具 编辑:程序博客网 时间:2024/05/17 22:34

UVA232:题目就不写了,主要是模拟单词的变换.注意必须要按照启示格的顺序来输出.在输出竖的单词时候要用一个矩阵来标记是否被访问过.当然还可以按照竖的方式写入然后再排序.

def cross(matrix,r,c):    mark = [[0]*c for i in range(r)]    def test(i,j):#检查一个白格是不是启示格        #if(matrix[i][j]=='U'):print(mark)        if(i==0 or j==0):return True        elif(matrix[i-1][j] == '*' or matrix[i][j-1]=='*'):return True        else:return False    i = 0;across = ''    while(i<r):        j = 0        while(j<c):            #print(matrix[i][j])            if(matrix[i][j]!='*' and test(i,j)):                across = ''                across+=matrix[i][j]                while(j+1<c and matrix[i][j+1]!='*'):across+=matrix[i][j+1];j+=1                j+=1                print(across)            else: j+=1        i+=1    print('Down:')    i = 0;across = ''    while(i<r):        j = 0        while(j<c):            if(matrix[i][j]!='*' and test(i,j) and mark[i][j]!=1):                across = ''                mark[i][j] = 1#标记已被访问过                across+=matrix[i][j]                _i = i;                while(_i+1<r and matrix[_i+1][j]!='*'):                    #print(_i+1,j)                    across+=matrix[_i+1][j]                    mark[_i+1][j] = 1                    _i+=1                j+=1                print(across)            else: j+=1        i+=1

UVA1368:DNA序列

只需要一列一列的进行比较就可以了,因为每一个位置的DNA都是独立的,与其它DNA无关

def Hamming(buf,m,n):    ans = ''    diff = 0    for j in range(n):        count = {'A':0,'C':0,'G':0,'T':0}        max = 0        for i in range(m):            count[buf[i][j]]+=1            if(count[buf[i][j]] > max):                max = count[buf[i][j]]                max_alpha = buf[i][j]            elif(count[buf[i][j]] == max):#比较字典序                if(buf[i][j]<max_alpha):                    max = count[buf[i][j]]                max_alpha = buf[i][j]        ans += max_alpha        diff += (m - max)    print(ans,diff)Hamming(['TATGATAC','TAAGCTAC','AAAGATCC','TGAGATAC','TAAGATGT'],5,8)

UVA202,这个题目的关键不是去判断小数,而是判断每一次的余数,只要余数重复那么小数就会重复的.想到这一点就不难了.

def Repeating(a,b):    ans1 = a//b    a = a%b    tmp = ''    ans2 = str((a*10)//b)    mark_store = []    while(True):        a = (a*10)%b        tmp = (a*10)//b        if(a in mark_store):break        else:            mark_store.append(a)            ans2 += str(tmp)    m = ans2[:-1]    print(str(ans1)+'.'+'(%s)'%(m),len(m))

UVA10340:这个题目关键是要逆着思考,考虑s字符串中的字符是否可以在t中按顺序找到,即只能向后查找.这样就能很容易的判断了.O(m+n)的复杂度。

def Allinall(s,t):#s-->t??    index = -1    for ch in s:        index = t.find(ch,index+1)        if(index == -1):print('NO');return False    print('YES')Allinall('dc','abcde')

UVA1587,此题关键是想到将输入标准化,统计边的情况之后进行检验.一定满足3种的分布.3条不同的边,2条相同,3条都一样.

def Box(L,W):    def mysort():        for i in range(6):            if(L[i]<W[i]):L[i],W[i] = W[i],L[i]    mysort()    X = [(L[i],W[i]) for i in range(6)]    Count = {}    for each in X:        if str(each) not in Count:            Count[str(each)] = 1        else:Count[str(each)] += 1    if(len(Count)==3):        print(Count)        for each,val in Count.items():            if(val != 2):print('Impossible 4');return        print('Possible')    elif(len(Count)==2):        test = [x for k,x in Count.items()]        test.sort()        if (test!=[2,4]):print('Impossible 8');return        print('Possible')    elif(len(Count)==1):        for each,val in Count.items():            if(Count[each]!=6):print('Impossible 12');return        print('Possible')    else:print('Impossible');returnBox([3,3,4,4,4,4],[3,3,5,3,3,3])

UVA1588,有个陷阱要注意,注意有两种模拟的方向.直接模拟,先放入长一点的长条,然后从长的长条每一个点开始遍历.然后放入短的长条进行遍历,最后取最小值

def Kickdown(h1,h2):    n1 = len(h1);n2 = len(h2)    def geth(i):        if(i>=n1):return 0        else: return h1[i]    def geth2(i):        if(i>=n2):return 0        else: return h2[i]    for i in range(n1+1):        if(geth(i)+h2[0]<=3):            test = True            for j in range(1,n2):                if(geth(i+j)+h2[j]>3):test = False;break            if(test):ans1 = max(n2+i,n1);break    for i in range(n2+1):#遍历n2        if(h1[0]+geth2(i)<=3):            test = True            for j in range(1,n1):                if(h1[j]+geth2(i+j)>3):test = False;break            if(test):ans2 = max(n1+i,n2);break    print(min(ans1,ans2))
0 0