【程序设计实习】第三次上机复盘

05:加密的病历单

小英是药学专业大三的学生,暑假期间获得了去医院药房实习的机会。
在药房实习期间,小英扎实的专业基础获得了医生的一致好评,得知小英在计算概论中取得过好成绩后,主任又额外交给她一项任务,解密抗战时期被加密过的一些伤员的名单。
经过研究,小英发现了如下加密规律(括号中是一个“原文 -> 密文”的例子)
1.原文中所有的字符都在字母表中被循环左移了三个位置(dec -> abz)
2.逆序存储(abcd -> dcba )
3.大小写反转(abXY -> ABxy)

输入

一个加密的字符串。(长度小于50且只包含大小写字母)

输出

输出解密后的字符串。

样例输入

1
GSOOWFASOq

样例输出

1
Trvdizrrvj

Solution

其实就两个事情 一个是大小写转换是用swapcase() 另一个就是ascil码与字符间的转换
字符->ascil码 使用ord ascil码->字符 使用chr
下面看代码:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
x=input()
l=len(x)
res_1=x.swapcase()
res_2=res_1[::-1]
res_3=[]
for i in range(0,l):
    if res_2[i]=='X':
        res_3.append('A')
    elif res_2[i]=='Y':
        res_3.append('B')
    elif res_2[i]=='Z':
        res_3.append('C')
    elif res_2[i]=='x':
        res_3.append('a')
    elif res_2[i]=='y':
        res_3.append('b')
    elif res_2[i]=='z':
        res_3.append('c')
    else:
        t=ord(res_2[i])
        t+=3
        res_3.append(chr(t)) 
for i in range(0,l):
    print(res_3[i],end='')

06:字符串最大跨距

描述

有三个字符串S,S1,S2,其中,S长度不超过300,S1和S2的长度不超过10。想检测S1和S2是否同时在S中出现,且S1位于S2的左边,并在S中互不交叉(即,S1的右边界点在S2的左边界点的左侧)。计算满足上述条件的最大跨距(即,最大间隔距离:最右边的S2的起始点与最左边的S1的终止点之间的字符数目)。如果没有满足条件的S1,S2存在,则输出-1。
例如,S = “abcd123ab888efghij45ef67kl”, S1=“ab”, S2=“ef”,其中,S1在S中出现了2次,S2也在S中出现了2次,最大跨距为:18。

输入

三个串:S, S1, S2,其间以逗号间隔(注意,S, S1, S2中均不含逗号和空格);

输出

S1和S2在S最大跨距;若在S中没有满足条件的S1和S2,则输出-1。

样例输入

1
abcd123ab888efghij45ef67kl,ab,ef

样例输出

1
18

Solution

做的时候忘记了rfind函数,但是如果用两次[::-1]应该也能做
然后就不难了
下面看代码:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
lst=input().split(',')
s=lst[0]
a=lst[1]
b=lst[2]
l=s.find(a)
r=s.rfind(b)
if l==-1 or r==-1:
    print(-1)
    exit()
if r-l>=len(a):
    print(r-l-len(a))
else:
    print(-1)

09:话题焦点人物

描述

微博提供了一种便捷的交流平台。一条微博中,可以提及其它用户。例如Lee发出一条微博为:“期末考试顺利 @Kim @Neo”,则Lee提及了Kim和Neo两位用户。
我们收集了N(1 < N < 10000)条微博,并已将其中的用户名提取出来,用小于等于100的正整数表示。
通过分析这些数据,我们希望发现大家的话题焦点人物,即被提及最多的人(题目保证这样的人有且只有一个),并找出那些提及它的人。

输入

输入共两部分:
第一部分是微博数量N,1 < N < 10000。
第二部分是N条微博,每条微博占一行,表示为:
发送者序号a,提及人数k(0 < = k < = 20),然后是k个被提及者序号b1,b2…bk;
其中a和b1,b2…bk均为大于0小于等于100的整数。相邻两个整数之间用单个空格分隔。

输出

输出分两行:
第一行是被提及最多的人的序号;
第二行是提及它的人的序号,从小到大输出,相邻两个数之间用单个空格分隔。同一个序号只输出一次。

样例输入

1
2
3
4
5
6
5
1 2 3 4
1 0
90 3 1 2 4
4 2 3 2
2 1 3

样例输出

1
2
3
1 2 4

Solution

这道题一直A不掉的原因是什么呢 就是我已经想到了不管是用list模拟set还是直接用set 都要去重,但是重的还要计入次数

  • 笔者注:此题用dict嵌套的dict做更为方便

下面看代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
n=int(input())
ans=[0]
res=[0]
for i in range(1,101):
    ans.append(0)
    res.append([])
for i in range(0,n):
    k=input().split()
    t=int(k[0])
    z=int(k[1])
    for j in range(2,z+2):
        x=int(k[j])
        ans[x]+=1
        if t in res[x]:
            pass
        else:
            res[x].append(t)
mi=max(ans)
mixx=ans.index(mi)
print(mixx)
res[mixx].sort()
for i in res[mixx]:
    print(i,end=' ')

10:判断元素是否存在

描述

有一个集合M是这样生成的: (1) 已知 k 是集合 M 的元素; (2) 如果 y 是 M 的元素,那么, 2y+1 和 3y+1 都是 M 的元素; (3) 除了上述二种情况外,没有别的数能够成为 M 的一个元素。
问题:任意给定 k 和 x,请判断 x 是否是 M 的元素。这里的 k是无符号整数,x 不大于 100000, 如果是,则输出YES,否则,输出 NO

输入

输入整数 k 和 x, 逗号间隔。

输出

如果是,则输出 YES,否则,输出NO

样例输入

1
0,22

样例输出

1
YES

Solution

有点像C++ 简单递归即可
但是由于python中碰到递归还比较少,我就放上来了

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
def check(x):
    global n
    if x>n:
        return False
    if x==n:
        return True
    return check(2*x+1) or check(3*x+1)
lst=input().split(',')
k=int(lst[0])
n=int(lst[1])
if k>n:
    print("NO")
    exit()
t=check(k)
if t==True:
    print("YES")
else:
    print("NO")
本博客已稳定运行
发表了27篇文章 · 总计103.29k字
使用 Hugo 构建
主题 StackJimmy 设计