蓝桥杯刷题总结---第一周

一.题目 1110: 2^k进制数

设r是个2^k 进制数,并满足以下条件:
(1)r至少是个2位的2^k 进制数。
(2)作为2^k 进制数,除最后一位外,r的每一位严格小于它右边相邻的那一位。
(3)将r转换为2进制数q后,则q的总位数不超过w。
在这里,正整数k(1≤k≤9)和w(k〈w≤30000)是事先给定的。

问:满足上述条件的不同的r共有多少个?
我们再从另一角度作些解释:设S是长度为w 的01字符串(即字符串S由w个“0”或“1”组成),S对应于上述条件(3)中的q。将S从右起划分为若干个长度为k 的段,每段对应一位2^k进制的数,如果S至少可分成2段,则S所对应的二进制数又可以转换为上述的2^k 进制数r。
例:设k=3,w=7。则r是个八进制数(2^3=8)。由于w=7,长度为7的01字符串按3位一段分,可分为3段(即1,3,3,左边第一段只有一个二进制位),则满足条件的八进制数有:
2位数:高位为1:6个(即12,13,14,15,16,17),高位为2:5个,…,高位为6:1个(即67)。共6+5+…+1=21个。
3位数:高位只能是1,第2位为2:5个(即123,124,125,126,127),第2位为3:4个,…,第2位为6:1个(即167)。共5+4+…+1=15个。
所以,满足要求的r共有36个。

def jie(n):
    if n==1 or n==0:
        return 1
    else:
        return jie(n-1)*n
def c(m,n):
    return jie(m)/(jie(n)*jie(m-n))
while True:
    try:
        a,b=map(eval,input().split())
        wei=2**a
        ans=0
        for _ in range(2,min(wei,b//a+1)):
            ans+=c(wei-1,_)
        if b%a==0:
            print(int(ans))
        else:
            print(int(ans+c(wei-1,b//a+1)-c(wei-(2**(b%a)),b//a+1)))
    except:
        break

二.题目 1096: Minesweeper

Minesweeper Have you ever played Minesweeper? This cute little game comes with a certain operating system whose name we can't remember. The goal of the game is to find where all the mines are located within a M x N field. The game shows a number in a square which tells you how many mines there are adjacent to that square. Each square has at most eight adjacent squares. The 4 x 4 field on the left contains two mines, each represented by a ``*'' character. If we represent the same field by the hint numbers described above, we end up with the field on the right: *... .... .*.. .... *100 2210 1*10 1110

from collections import deque
num=1
while True:
    n,m=map(eval,input().split())
    if n==0 and m==0:
        break
    is_map=[]
    bfs=deque()
    for i in range(n):
        s=input()
        temp=[]
        for j in range(m):
            if s[j]=='*':
                bfs.append([i,j])
                temp.append(s[j])
            else:
                temp.append(0)
        is_map.append(temp)
    while len(bfs)!=0:
        i,j=bfs.popleft()
        for ii in range(max(0,i-1),min(n,i+2)):
            for jj in range(max(0,j-1),min(m,j+2)):
                if is_map[ii][jj]!='*':
                    is_map[ii][jj]+=1
    print("Field #{}:".format(num))
    num+=1
    for i in range(n):
        for j in range(m):
            print(is_map[i][j],end='')
        print()
    print()

三.题目 1115: DNA

输出输入包含多组测试数据。第一个整数N(N<=15),N表示组数,每组数据包含两个整数a,b。a表示一个单位的DNA串的行数,a为奇数且 3<=a<=39。b表示重复度(1<=b<=20)。输出DNA的形状,每组输出间有一空行。

q=eval(input())
for _ in range(q):
    n,m=map(eval,input().split())
    for i in range(m):
        for j in range(n-1):
            if j<n//2:
                print("{}{}{}{}".format(' '*j,'X',' '*(n-2*j-2),'X'))
            elif j==n//2:
                print("{}{}".format(" "*j,'X'))
            else:
                print("{}{}{}{}".format(' '*(n-1-j),'X',' '*(-n+j+j),"X"))
    print("{}{}{}".format('X',' '*(n-2),'X'))
    print()

四.题目 1255: 蓝桥杯算法提高-能量项链

在Mars星球上,每个Mars人都随身佩带着一串能量项链。在项链上有 N颗能量珠。能量珠是一颗有头标记与尾标记的珠子,这些标记对应着某个正整数。并且,对于相邻的两颗珠子,前一颗珠子的尾标记一定等于后一颗珠子的头标 记。因为只有这样,通过吸盘(吸盘是Mars人吸收能量的一种器官)的作用,这两颗珠子才能聚合成一颗珠子,同时释放出可以被吸盘吸收的能量。如果前一颗 能量珠的头标记为m,尾标记为r,后一颗能量珠的头标记为r,尾标记为n,则聚合后释放的能量为m*r*n(Mars单位),新产生的珠子的头标记为m, 尾标记为n。
需要时,Mars人就用吸盘夹住相邻的两颗珠子,通过聚合得到能量,直到项链上只剩下一颗珠子为止。显然,不同的聚合顺序得到的总能量是不同的,请你设计一个聚合顺序,使一串项链释放出的总能量最大。
例如:设N=4,4颗珠子的头标记与尾标记依次为(2,3) (3,5) (5,10) (10,2)。我们用记号◎表示两颗珠子的聚合操作,(j◎k)表示第j,k两颗珠子聚合后所释放的能量。则第4、1两颗珠子聚合后释放的能量为:
(4◎1)=10*2*3=60。
这一串项链可以得到最优值的一个聚合顺序所释放的总能量为
((4◎1)◎2)◎3)=10*2*3+10*3*5+10*5*10=710。

n=eval(input())
num=list(map(eval,input().split()))
ans=0
while len(num)>2:
    i=num.index(min(num))
    ans+=num[i]*num[(i+1)%len(num)]*num[(i+len(num)-1)%len(num)]
    del num[i]
ans+=max(num)*max(num)*min(num)
print(int(ans))

五.题目 1117: K-进制数

考虑包含N位数字的K-进制数. 定义一个数有效, 如果其K-进制表示不包含两连续的0.考虑包含N位数字的K-进制数. 定义一个数有效, 如果其K-进制表示不包含两连续的0.
例:
1010230 是有效的7位数
1000198 无效
0001235 不是7位数, 而是4位数.
给定两个数N和K, 要求计算包含N位数字的有效K-进制数的总数.
假设2 <= K <= 10; 2 <= N; 4 <= N+K <= 18.

N=eval(input())
K=eval(input())
ans=0
def c(m,n):
    ans=1
    for i in range(n):
        ans=ans*((m-i)/(i+1))
    return ans
for i in range(N):
    ans+=((K-1)**(N-i))*c(N-i,i)
print(int(ans))

六.题目 1111: Cylinder

Using a sheet of paper and scissors, you can cut out two faces to form a cylinder in the following way:
Cut the paper horizontally (parallel to the shorter side) to get two rectangular parts.
From the first part, cut out a circle of maximum radius. The circle will form the bottom of the cylinder.
Roll the second part up in such a way that it has a perimeter of equal length with the circle's circumference, and attach one end of the roll to the circle. Note that the roll may have some overlapping parts in order to get the required length of the perimeter.
Given the dimensions of the sheet of paper, can you calculate the biggest possible volume of a cylinder which can be constructed using the procedure described above?

import math
from  math import *
while True:
    a,b=map(eval,input().split())
    if a==0:
        break
    v1,v2,v3=0,0,0
    if a<=b-a*math.pi:
        v1=math.pi*(a**3)/4
    x=min(a,b/(math.pi+1))
    v2=math.pi*a*x*x/4
    x=min(a/math.pi,2*b/3)
    v3=math.pi*x*x*(b-x)/4
    print("{:.3f}".format(max(v1,v2,v3)))

七.题目 1427: 蓝桥杯2013年第四届真题-买不到的数目

小明开了一家糖果店。他别出心裁:把水果糖包成4颗一包和7颗一包的两种。糖果不能拆包卖。
小朋友来买糖的时候,他就用这两种包装来组合。当然有些糖果数目是无法组合出来的,比如要买  10  颗糖。
你可以用计算机测试一下,在这种包装情况下,最大不能买到的数量是17。大于17的任何数字都可以用4和7组合出来。
本题的要求就是在已知两个包装的数量时,求最大不能组合出的数字。

a,b=map(eval,input().split())
a,b=min(a,b),max(a,b)
for i in range((a*(b-1))+1,0,-1):
    j=i
    while j>0:
        if j%b==0 or j%a==0:
            break
        else:
            j-=b
    if j<0:
        print(i)
        break

八.题目 1434: 蓝桥杯历届试题-回文数字

观察数字:12321,123321  都有一个共同的特征,无论从左到右读还是从右向左读,都是相同的。这样的数字叫做:回文数字。
本题要求你找到一些5位或6位的十进制数字。满足如下要求:
该数字的各个数位之和等于输入的整数。

n=eval(input())
def s(m,n):
    ans=[]
    if m==2:
        for i in range(10,100):
            if  i%10+i//10==n:
                ans.append(str(i))
        return ans
    elif m==3:
        for i in range(100,1000):
            if i%10+i//100+(i//10)%10==n:
                ans.append(str(i))
        return ans
g=[]
for i in range(9,-1,-1):
    if (n-i)/2>18 or (n-i)%2==1:
        continue
    else:
        ans=s(2,(n-i)//2)

        for j in ans:
            ss=j+str(i)+j[::-1]
            g.append(eval(ss))
g.sort()
for j in g:
    print(j)
if n%2==1 or n//2>27:
    pass
else:
    ans=s(3,n//2)
    for j in ans:
        print(j+j[::-1])
if n>=55:
    print(-1)

九.题目 1432: 蓝桥杯2013年第四届真题-剪格子

问题描述
如下图所示,3  x  3  的格子中填写了一些整数。
+--*--+--+
|10*  1|52|
+--****--+
|20|30*  1|
*******--+
|  1|  2|  3|
+--+--+--+ 
我们沿着图中的星号线剪开,得到两个部分,每个部分的数字和都是60。
本题的要求就是请你编程判定:对给定的m  x  n  的格子中的整数,是否可以分割为两个部分,使得这两个区域的数字和相等。
如果存在多种解答,请输出包含左上角格子的那个区域包含的格子的最小数目。 
如果无法分割,则输出  0。

n,m=map(eval,input().split())
grid=[]
s=0
for _ in range(m):
    temp=list(map(eval,input().split()))
    s+=sum(temp)
    grid.append(temp)
isvisited=[]
for i in range(m):
    temp=[]
    for j in range(n):
        temp.append(False)
    isvisited.append(temp)
count=100
def dfs(temp_s,i,j,grid,isvisited,ans):
    temp_s+=grid[i][j]
    isvisited[i][j]=True
    global  count
    global s
    if temp_s==s//2 and count>ans:
        count=ans
    if temp_s>s//2:
        return
    if i>0 and not isvisited[i-1][j]:
        dfs(temp_s,i-1,j,grid,isvisited,ans+1)
        isvisited[i-1][j]=False
    if j>0 and not isvisited[i][j-1]:
        dfs(temp_s,i,j-1,grid,isvisited,ans+1)
        isvisited[i][j-1] = False
    if i<len(grid)-1 and not isvisited[i+1][j]:
        dfs(temp_s,i+1,j,grid,isvisited,ans+1)
        isvisited[i+1][j] = False
    if j<len(grid[0])-1 and not isvisited[i][j+1]:
        dfs(temp_s,i,j+1,grid,isvisited,ans+1)
        isvisited[i][j+1] = False
if s%2==1:
    print(0)
else:
    dfs(0,0,0,grid,isvisited,1)
    print(count)

十.题目 1433: 蓝桥杯2013年第四届真题-危险系数

问题描述
抗日战争时期,冀中平原的地道战曾发挥重要作用。
地道的多个站点间有通道连接,形成了庞大的网络。但也有隐患,当敌人发现了某个站点后,其它站点间可能因此会失去联系。
我们来定义一个危险系数DF(x,y):
对于两个站点x和y  (x  !=  y),  如果能找到一个站点z,当z被敌人破坏后,x和y不连通,那么我们称z为关于x,y的关键点。相应的,对于任意一对站点x和y,危险系数DF(x,y)就表示为这两点之间的关键点个数。
本题的任务是:已知网络结构,求两站点之间的危险系数。

m,n=map(eval,input().split())
grid=[]
isvisited=[]
visit_num=[]
for _ in range(m):
    temp=[]
    visit_num.append(0)
    isvisited.append(False)
    for __ in range(m):
        temp.append(0)
    grid.append(temp)
for _ in range(n):
    i,j=map(eval,input().split())
    grid[i-1][j-1]=1
    grid[j-1][i-1]=1
start,end=map(eval,input().split())
num=0
isvisited[start-1]=True
def dfs(grid,i,j):
    global m
    global start
    global end
    global num
    if j+1==end:
        num+=1
        for _ in range(m):
            if isvisited[_]:
                visit_num[_]+=1
    for ii in range(m):
        if not isvisited[ii] and grid[j][ii]==1 :
            isvisited[ii]=True
            dfs(grid,j,ii)
            isvisited[ii]=False
for ii in range(m):
    if not isvisited[ii] and grid[start-1][ii]==1 :
        isvisited[ii]=True
        dfs(grid,start-1,ii)
        isvisited[ii]=False
ans=-1
for i in range(m):
    if visit_num[i]==num:
        ans+=1
if ans==-1:
    print(-1)
else:
    print(ans-1)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值