洛谷入门题 - 4

2019-10-30 Views 洛谷 编程2040字10 min read

本系列文章选取大量新手村题目,为初学者讲解编程的一些相关技巧。本文使用的编程语言为 python,总共 10 道题,涵盖顺序与分支、循环和数组、字符串等内容。
本文涉及的题目:P1138、P1179、P1150、P1151、P1152、P1307、P1304、P1161、P1317、P1319

P1138

现有 nn 个正整数,n10000n≤10000,要求出这 nn 个正整数中的第 kk 个最小整数(相同大小的整数只计算一次),k1000k≤1000,正整数均小于 3000030000

用python做这题几乎可以算是作弊,因为只需要用sort方法重新以小到大排列数组就可以,但要注意删除相同的选项,这里就要用到set,代码如下:

n, k = input().split()
k = int(k)
num = input().split()

for i in range(0,len(num)):
    num[i] = int(num[i])

num = list(set(num))
num.sort()

if k > len(num) - 1:
    print("NO RESULT")
else:
    print(num[k-1])

P1179

请统计某个给定范围 [L,R][L, R] 的所有整数中,数字 22 出现的次数。 比如给定范围 [2,22][2, 22],数字 22 在数 22 中出现了 11 次,在数 1212 中出现 11 次,在数 2020 中出现 11 次,在数 21 中出现 11 次,在数 2222 中出现 22 次,所以数字 22 在该范围内一共出现了 66 次。这题根P1980很相像,如果想要了解解法思路可以查看这篇文章,代码如下:

a = input().split()
count = 0
s = int(a[0])
e = int(a[1])

for i in range(s,e+1):
    index = 0
    d = 0
    m = str(i)
    while d != -1: 
        d = m.find("2",index)
        if d >= 0:
            count += 1
            index = d + 1

print(count)

P1150

Peter 有 n 根烟,他每吸完一根烟就把烟蒂保存起来,k(k>1) 个烟蒂可以换一个新的烟,那么 Peter 最终能吸到多少根烟呢?

代码如下:

a = input().split()
n, k = int(a[0]), int(a[1])
temp = n // k
remain = n - temp * k

while temp != 0:
    n += temp
    remain += temp
    temp = remain // k
    remain = remain - temp * k

print(n)

P1151

对于一个五位数 a1a2a3a4a5a_1a_2a_3a_4a_5,可将其拆分为三个子数:
sub1=a1a2a3sub_1=a_1a_2a_3
sub2=a2a3a4sub_2=a_2a_3a_4
sub3=a3a4a5sub_3=a_3a_4a_5
例如,五位数 2020720207 可以拆分成
sub1=202sub_1=202
sub2=020(=20)sub_2=020 (=20)
sub3=207sub_3=207
现在给定一个正整数 KK,要求你编程求出 10000100003000030000 之间所有满足下述条件的五位数,条件是这些五位数的三个子数 sub1,sub2,sub3sub_1,sub_2,sub_3 都可被 KK 整除。

代码如下:

a = int(input())
count = 1

for i in range(10000,30001):
    a1 = int(str(i)[0:3])
    a2 = int(str(i)[1:4])
    a3 = int(str(i)[2:5])
    if a1 % a == 0 and a2 % a == 0 and a3 % a == 0:
        print(i)
        count = 0

if count:
    print("No")

P1152

一个 nn 个元素的整数数组,如果数组两个连续元素之间差的绝对值包括了 [1,n1][1,n-1] 之间的所有整数,则称之符合 “欢乐的跳”,如数组 14231 4 2 3 符合 “欢乐的跳”,因为差的绝对值分别为:3,2,13,2,1。 给定一个数组,你的任务是判断该数组是否符合 “欢乐的跳”。

这题只需要我们判断差的绝对值是否能包括所有的列表内的整数即可,代码如下:

a = input().split()
n = int(a[0])
del a[0]
test = []

for i in range(0,n):
    a[i] = int(a[i])
    test.append(i+1)

del test[len(test) - 1]

for i in range(0,n - 1):
    temp = abs(a[i + 1] - a[i])
    if temp in test:
        test[test.index(temp)] = 0

if max(test) > 0:
    print("Not jolly")
else:
    print("Jolly")

P1307

给定一个整数,请将该数各个位上数字反转得到一个新数。新数也应满足整数的常见形式,即除非给定的原数为零,否则反转后得到的新数的最高位数字不应为零(参见样例 2)。

代码如下:

s = input()
k = 0

if s[0] == "-":
    s = s[1:]
    k = 1
    
s = s[len(s)-1::-1]

while s[0] == "0" and len(s) != 1:
    s = s[1:]

if k == 1:
    print("-" + s)
else:
    print(s)

P1304

输入一个偶数 N(N<=10000),验证 4~N 所有偶数是否符合哥德巴赫猜想:任一大于 2 的偶数都可写成两个质数之和。如果一个数不止一种分法,则输出第一个加数相比其他分法最小的方案。例如 10,10=3+7=5+5,则 10=5+5 是错误答案。

这题比较难的地方就是判断质数,这个我们通过循环判断即可,只要这个数不能被除了本身和1以外的数整除那么他就是质数,代码如下:

s = int(input())

def isPrime(n):
    for i in range(2,n // 2 + 1):
        if n % i == 0:
            return False
    return True

for i in range(4,s+1,2):
    for k in range(2, i - 1):
        if isPrime(k) and isPrime(i - k):
            print(str(i) + "=" + str(k) + "+" + str(i - k))
            break

P1161

在一条无限长的路上,有一排无限长的路灯,编号为1,2,3,4…

每一盏灯只有两种可能的状态,开或者关。如果按一下某一盏灯的开关,那么这盏灯的状态将发生改变。如果原来是开,将变成关。如果原来是关,将变成开。

在刚开始的时候,所有的灯都是关的。小明每次可以进行如下的操作:

指定两个数,a,ta,t(aa 为实数,tt 为正整数)。将编号为[a],[2×a],[3×a],…,[t×a] 的灯的开关各按一次。其中[k]表示实数k的整数部分。

在小明进行了n次操作后,小明突然发现,这个时候只有一盏灯是开的,小明很想知道这盏灯的编号,可是这盏灯离小明太远了,小明看不清编号是多少。

幸好,小明还记得之前的n次操作。于是小明找到了你,你能帮他计算出这盏开着的灯的编号吗?

这题我们只需要用数组存储结果即可,代码如下:

s = int(input())
result = []

for i in range(0,2000000):
    result.append("0")

for i in range(0,s):
    m = input().split()
    a = float(m[0])
    t = int(m[1])
    for k in range(1,t+1):
        temp = int(a * k)
        if result[temp] == "0":
            result[temp] = "1"
        else:
            result[temp] = "0"

print(result.index("1"))

P1317

一组数,分别表示地平线的高度变化。高度值为整数,相邻高度用直线连接。找出并统计有多少个可能积水的低洼地?

如图:地高变化为 0 1 0 2 1 2 0 0 2 0

这题需要注意的是有可能有些地可能是平的,这要加入代码的判断

代码如下:

s = int(input())
num = input().split()
count = 0

for i in range(0,s):
    num[i] = int(num[i])

for i in range(1,s - 2):
    if num[i] >= num[i+1] and num[i+1] <= num[i+2]:
        if num[i+1] == num[i+2]:
            count -= 1
        count += 1

print(count)

P1319

设某汉字由 N × N 的 0 和 1 的点阵图案组成。

我们依照以下规则生成压缩码。连续一组数值:从汉字点阵图案的第一行第一个符号开始计算,按书写顺序从左到右,由上至下。第一个数表示连续有几个 0,第二个数表示接下来连续有几个 1,第三个数再接下来连续有几个 0,第四个数接着连续几个 1,以此类推……

例如:以下汉字点阵图案:

0001000
0001000
0001111
0001000
0001000
0001000
1111111

对应的压缩码是: 7 3 1 6 1 6 4 3 1 6 1 6 1 3 7 (第一个数是 N , 其余各位表示交替表示 0 和 1 的个数,压缩码保证 N × N = 交替的各位数之和)

代码如下:

a = input().split()
n = int(a[0])
a= a[1:]
temp = 0
count = 0

for i in range(0,len(a)):
    a[i] = int(a[i])

while len(a) != 0:
    for i in range(0,a[0]):
        if count == n:
            print("")
            count = 0
        if temp == 0:
            print(0,end="")
            count += 1
        else:
            print(1,end="")
            count += 1

    if temp == 0:
        temp = 1
    else:
        temp = 0

    del a[0]

注:如有更简单的代码欢迎在评论区留言哦!



logo   WRITTEN BY:Serence

一个程序员和文艺青年的博客!

本文章采用CC BY-NC-SA 4.0进行许可。转载请注明出处!

上一篇

诗与话 - 4


下一篇

诗与话 - 3