蓝桥杯刷题

1.几个人一起出去吃饭是常有的事。但在结帐的时候,常常会出现一些争执。

 

现在有 n个人出去吃饭,他们总共消费了 S 元。其中第 i 个人带了 ai​元。幸运的是,所有人带的钱的总数是足够付账的,但现在问题来了:每个人分别要出多少钱呢?

为了公平起见,我们希望在总付钱量恰好为 S 的前提下,最后每个人付的钱的标准差最小。这里我们约定,每个人支付的钱数可以是任意非负实数,即可以不是 1 分钱的整数倍。你需要输出最小的标准差是多少。

标准差的介绍:标准差是多个数与它们平均数差值的平方平均数,一般用于刻画这些数之间的"偏差有多大"。形式化地说,设第 i 个人付的钱为 bi​ 元,那么标准差为 :

输入描述
第一行包含两个整数 n、S;

第二行包含 nn个非负整数 a1​, ⋯, an​。

其中,n≤5×10^5,0≤ai​≤10^9 。

 S=\sqrt{\frac{1}{n}\sum_{i=1}^{n}\left ( b_{i} -\frac{1}{n}\sum_{i=1}^{n}\left ( b_{i} \right )\right )^{^2}}

输出描述
输出最小的标准差,四舍五入保留 4 位小数。

保证正确答案在加上或减去 10^{−9} 后不会导致四舍五入的结果发生变化。

输入输出样例
示例

输入

5 2333
666 666 666 666 666
输出

0.0000
运行限制
最大运行时间:1s
最大运行内存: 256M

题解:

from math import*
n, s = map(int, input().split())
a = list(map(int, input().split()))
a.sort()
avg = s/n
su = 0
for i in range(n):
    if a[i]*(n-i) < s:
        su += pow(a[i]-avg, 2)
        s -= a[i]
    else:
        cur_avg = su/(n-i)
        su += pow(cur_avg-avg, 2)*(n-i)
        break
print("{:.4f}".format(sqrt(su/(n))))
思路:
如果每人带的钱够多,人均完全一样,bi = S/n = avg,标准差X = 0。
不过总有人钱不够,分 两种 情况讨论:
(1)第i人带的钱不够平均数avg,他只能出他带的全部钱ai。
(2)第i人带的钱比平均数avg多,他可以多摊一些。
求解步骤:
(1)对ai从小到大排序;
(2)前一部分人的钱不够,那么就出他们所有的钱;
(3)从总付钱数中扣除前一部分人出的钱,得剩余钱数为S’ ,以及
后一部分人的出钱平均数avg’ 。
(4)后一部分人的钱多,他们多出一些。怎么出?这部分人也分两
类:
(i)比较有钱的,但是他的钱也不够avg’ ,那么他的钱还是要全
出;
(ii)非常有钱的,不管怎么摊他都有富余。
2.

小蓝给学生们组织了一场考试,卷面总分为 100 分,每个学生的得分都是一个 0 到 100 的整数。

如果得分至少是 60 分,则称为及格。如果得分至少为 85 分,则称为优秀。

请计算及格率和优秀率,用百分数表示,百分号前的部分四舍五入保留整 数。

输入描述

输入的第一行包含一个整数 n (1≤n≤10^4),表示考试人数。

接下来 n 行,每行包含一个 0 至 100 的整数,表示一个学生的得分。

输出描述

输出两行,每行一个百分数,分别表示及格率和优秀率。百分号前的部分 四舍五入保留整数。

输入输出样例

示例

输入

7
80
92
56
74
88
100
0

输出

71%
43%

 题解:

'''
n = int(input())
well = 0
ok = 0
for i in range(n):
  a = int(input())
  if a>=60:
    ok+=1
  elif a>=85:
    ok+=1
    well+=1
print("{:.0f}%".format(100*ok/n))
print("{:.0f}%".format(100*well/n))
'''
n = int(input())   #数据横着给的用split(),竖着给的不用,输入多个数的用map
well = 0
ok = 0
for i in range(n):
  a = int(input())
  if a>=85:
    ok+=1
    well+=1
  elif a>=60:
    ok+=1   #注意:python先执行if后再执行elif,如果像上面那种情况,只能执行ok+=1的选项,下面的well+=1无法执行
print("{:.0f}%".format(100*ok/n))
print("{:.0f}%".format(100*well/n))

绿色部分是错误的,这道题提醒注意if和elif的顺序逻辑关系

输出百分比

方式1:直接使用参数格式化:"{:.2%}"

方式2:格式化为float,然后处理成%格式: "{:.2f}%"

3.小蓝要把一个字符串中的字母按其在字母表中的顺序排列。

例如,LANQIAO 排列后为 AAILNOQ。

又如,GOODGOODSTUDYDAYDAYUP 排列后为 AADDDDDGGOOOOPSTUUYYY。

请问对于以下字符串,排列之后字符串是什么?

WHERETHEREISAWILLTHEREISAWAY

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 512M
s = list("WHERETHEREISAWILLTHEREISAWAY") #列表可以直接对字母进行排序
s.sort()
for i in s:
    print(i,end="")

4.

在 ISO 国际标准中定义了 A0 纸张的大小为 1189mm ×× 841mm, 将 A0 纸 沿长边对折后为 A1 纸, 大小为 841mm ×× 594mm, 在对折的过程中长度直接取 下整 (实际裁剪时可能有损耗)。将 A1 纸沿长边对折后为 A2 纸, 依此类推。

输入纸张的名称, 请输出纸张的大小。

输入格式

输入一行包含一个字符串表示纸张的名称, 该名称一定是 A0、A1、A2、 A3、A4、A5、A6、A7、A8、A9 之一。

输出格式

输出两行,每行包含一个整数,依次表示长边和短边的长度。

样例输入1

A0

样例输出1

1189
841

样例输入 2

A1

样例输出 2

841
594

题解:

#规律:长每次都等于宽,而宽等于长的一半。
n = input()
a = int(n[1])
l,w = 1189,841
for i in range(a):
  l,w = w,l//2
print(l)
print(w)

5.人类终于登上了火星的土地并且见到了神秘的火星人。人类和火星人都无法理解对方的语言,但是我们的科学家发明了一种用数字交流的方法。这种交流方法是这样的,首先,火星人把一个非常大的数字告诉人类科学家,科学家破解这个数字的含义后,再把一个很小的数字加到这个大数上面,把结果告诉火星人,作为人类的回答。

火星人用一种非常简单的方式来表示数字——掰手指。火星人只有一只手,但这只手上有成千上万的手指,这些手指排成一列,分别编号为 1,2,3……1,2,3……。火星人的任意两根手指都能随意交换位置,他们就是通过这方法计数的。

一个火星人用一个人类的手演示了如何用手指计数。如果把五根手指——拇指、食指、中指、无名指和小指分别编号为 1,2,3,4,51,2,3,4,5,当它们按正常顺序排列时,形成了 55 位数 1234512345,当你交换无名指和小指的位置时,会形成 55 位数 1235412354,当你把五个手指的顺序完全颠倒时,会形成 5432154321,在所有能够形成的 120120 个 55 位数中,1234512345 最小,它表示 11 ;1235412354 第二小,它表示 22 ;5432154321 最大,它表示 120120。下表展示了只有 33 根手指时能够形成的 66 个 33 位数和它们代表的数字:

三进制数

 123
 132
 213
 231
 312
 321

代表的数字

 1
 2
 3
 4
 5
 6

现在你有幸成为了第一个和火星人交流的地球人。一个火星人会让你看他的手指,科学家会告诉你要加上去的很小的数。你的任务是,把火星人用手指表示的数与科学家告诉你的数相加,并根据相加的结果改变火星人手指的排列顺序。输入数据保证这个结果不会超出火星人手指能表示的范围。

输入描述

第一行有一个正整数 N ,表示火星人手指的数目(1≤N≤10000)。

第二行是一个正整数 M,表示要加上去的小整数(1≤M≤100)。下一行是 1 到 N 这N 个整数的一个排列,用空格隔开,表示火星人手指的排列顺序。

输出描述

输出一行,这一行含有 N 个整数,表示改变后的火星人手指的排列顺序。每两个相邻的数中间用一个空格分开,不能有多余的空格。

输入输出样例

示例 1

输入

5
3
1 2 3 4 5

输出

1 2 4 5 3
思路
1.创建列表,利用循环将后面较大的元素排列到前面中
2.因为这个数字是递增上升的,我们最好让相邻数字交换,如果两个数字偏差过大,选择偏差较小的两个数进行交换。最后尾数进行一个递减排列,进行子序列翻转
比如:12345  =  1
交换5和4 -->12354  =  2
交换3和5-->12534    进行子序列翻转 12435  =  3
交换5和3-->12453  =  4
题解:
N=int(input())  #N相当于len(s)
M=int(input())  
nums=list(map(int,input().split()))
a=1
while a<=M:  #下M个排列循环M次
  for i in range(N-1,0,-1):
    if nums[i-1]<nums[i]:  #从后往前找第一个相邻升序列
      for j in range(N-1,i-1,-1):
        if nums[j]>nums[i-1]:  #从后往前找尽量小的大数
          nums[j],nums[i-1]=nums[i-1],nums[j]  #交换
          break
      for k in range((N-i)//2):  #反转子序列
        nums[i+k],nums[N-1-k]=nums[N-1-k],nums[i+k]
      break
  a+=1
for b in nums:
  print(b,end=" ")  #输出结果

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值