本题目比较困难,我们将信息传递出去,而且要满足最短的,那么其实只需要n-1条边,是一棵无向树。在数据结构中有“最小生成树”,有两个算法,分别是Kruskal(加边)及Prime(加点)。这个题目数据量比较小,不卡算法,你可以实现任一算法AC。题解所用的是Kruskal。

这个算法的思想可以这样理解,我将所有的边按照权值进行排序,我必定会先选择最小的边,怎么确定这个边可以用另一数据结构“并查集”,他也是一棵无向树。没有连接这条边肯定要选,所以也有点贪心的意思。最后n-1条边将n个点连接起来就是最小的。

#并查集
class UDFS:
def __init__(self, n):
self.n = n
self.parents = [i for i in range(n)]
self.ranks = [0 for i in range(n)]
def Find(self, a):
if a == self.parents[a]:
return a
self.parents[a] = self.Find(self.parents[a])
return self.parents[a]
def join(self, a, b):
parent_a = self.Find(a)
parent_b = self.Find(b)
if(parent_a!=parent_b):
self.parents[parent_a] = parent_b
return 1
return 0
n_nodes, n_edges = map(int, input().split())
edges = list()
for i in range(n_edges):
a, b, w = map(int, input().split())
edges.append((w, a , b))
dsu = UDFS(n_nodes+1)
edges.sort()
tot = 1
mi = 0
for edge in edges:
if(dsu.join(edge[1],edge[2])!=0):
mi = mi + edge[0]
tot = tot + 1
if(tot==n_nodes):
break
print (mi)

第一问是一个很经典的01背包问题,一个物品可以选一次,所以我们这时候的状态是从前一个状态过来的。当前物品是否可以放下,是不是更大都是需要我们考虑的。01背包只能选一次,我们可以优化只用一维dp数组,第二重循环需要倒着进行。

第二问是个很简单的贪心问题,我们可以选择体积最小的货物装上。

while True:
try:
m,n=map(int,input().split())
w=[0]*n
c=[0]*n
for i in range(n):
w[i],c[i]=map(int,input().split())
dp=[0]*(m+5)
for i in range (n):
for j in range(m, w[i]-1,-1):
dp[j]=max(dp[j],dp[j-w[i]]+c[i])
w.sort()
ans = 0
sum = 0
for i in range (n):
if sum+w[i] <= m :
sum += w[i]
ans = ans+1
else:
break
print(dp[m],ans)
except EOFError:
break

这个题目有些困难,我们需要知道这个人的车次,之后我们会找到人然后对应到这个车次。最终我们要查询的是车次,当然我们可以进行排序之后二分。不过这个题目有个更好用的东西,叫dict字典。也叫键值对,前面可以把放键,可以理解为就是一个下标,后面放值。所以就是人和车次的dict以及车次和人数的dict。这个“None”不能强转为数字,自己可以写个函数处理下。

def xstr(s):
if s is None:
return 0
return int(s)
n=int(input())
peo=dict()
for i in range(n):
data=list(map(str,input().split()))
peo.update(dict([(k,data[0]) for k in data[2:]]))
m=int(input())
trains=dict()
peos=list(map(str,input().split()))
for i in range(m):
t=xstr((trains.get(peo.get(peos[i]))))+1
trains.update({peo.get(peos[i]):t})
q=int(input())
for i in range(q):
train=input()
print(xstr((trains.get(train))))

这个题目我们可以采用常规做法,就是我们递归的时候可以统计移动次数。

当然也可以找到递推式,数量级大的情况就必须使用递推式了。

A->B=(上一次)A->C->B

B->C=(上一次)B->A->C

C->A=(上一次)C->B->A

我这里用了递归写法,我们可以设置变量去统计他们,在每次移动的时候去统计。

ans = []
def cal(a,c):
if(a=="A" and c=="B"):
ans[0] = ans[0]+1
if(a=="A" and c=="C"):
ans[1] = ans[1]+1
if(a=="B" and c=="A"):
ans[2] = ans[2]+1
if(a=="B" and c=="C"):
ans[3] = ans[3]+1
if(a=="C" and c=="A"):
ans[4] = ans[4]+1
if(a=="C" and c=="B"):
ans[5] = ans[5]+1
def Hanoi(n,a,b,c):
if n==0:
return
Hanoi(n-1, a, c, b)
cal(a,c)
Hanoi(n-1, b, a, c)
while True:
try:
n=int(input())
ans=[0]*6
Hanoi(n, "A", "B", "C")
print("A->B: ",ans[0])
print("A->C: ",ans[1])
print("B->A: ",ans[2])
print("B->C: ",ans[3])
print("C->A: ",ans[4])
print("C->B: ",ans[5])
except EOFError:
break

更python的写法,有可能获得超时

ans = dict()
def cal(a,c):
s=a+'->'+c+':'
ans.update({s:ans.get(s)+1})
def Hanoi(n,a,b,c):
if n==0:
return
Hanoi(n-1, a, c, b)
cal(a,c)
Hanoi(n-1, b, a, c)
while True:
try:
n=int(input())
ans = {'A->B:':0,'A->C:':0,'B->A:':0,'B->C:':0,'C->A:':0,'C->B:':0}
Hanoi(n, 'A', 'B', 'C')
for a in ans:
print(a,ans.get(a))
except EOFError:
break

其实我们可以给其中的8和2拿出来看看有多少个282,排列一定是282828282····

也就是28不断循环的,其中282的个数和2和8均有关,n个2就有n-1个282,m个8就有m个282,两者取小,当然不能是负数。

取值是ord函数

while True:
try:
s=input()
a=[0]*10
for c in s:
t = ord(c)-ord('0')
a[t] = a[t] + 1
print(max(0,min(a[2]-1,a[8])))
print('Happy Birthday!')
except EOFError:
break

这个一个比较复杂的循环题,我们可以将其分三种输出,前m/2行,中间行,后m/2行,前m/2行前面的空格分析下,为abs(i)个,*为(m - abs(i) + 1))个,中间行是n个*,然后依次类推。

至于中间用空行隔开,我们可以用一个旗子来表示,刚开始没有插旗子,不能输出空行,执行一次就插上了旗子,当然是否要输出空行要在插旗子之前。详见代码flag的操作。

python直接把字符串乘起来,很方便

flag = 0
while True:
try:
n = int(input())
if flag==1:
print()
flag = 1
m = n//2
for i in range (-m,m + 1):
if i < 0:
print(' ' * abs(i) + '*' *(m - abs(i) + 1))
elif i == 0:
print('*' * n)
else:
print(' ' * m + '*' * (m - i + 1))
except EOFError:
break

这是一个比较有趣的游戏,但是不同的思路实现起来难度可能不同,在这里推荐了一个比较简单的实现,

1.横或竖坐标均相同

2.在左上到右下的对角线上

3.在右上到左下对角线上

while True:
try:
x1,y1 = map(int,input().split())
x2,y2 = map(int,input().split())
x3,y3 = map(int,input().split())
if x1==x2 and x2==x3 or y1==y2 and y2==y3:
print('Win')
elif x1==y1 and x2==y2 and x3==y3:
print('Win')
elif x1+y1==4 and x2+y2==4 and x3+y3==4:
print('Win')
else:
print('Continue')
except EOFError:
break

空圆柱体的体积,体积为底面积高,

圆环面积为(R*R-r*r)PI

可以使用math包里的PI

import math

while True:

try:

R,r,h = map(float,input().split())

print ('%.2f' %(math.pi*h*(R*R-r*r)))

except EOFError:

break

10个口罩一定会浪费掉,所以你买到y个口罩,买x个一次,次数为y/x

python的整数除法需要"//"

n,m=map(int,input().split())

print (m//n)

简单C语言输出,可以复制粘贴,尽量减少错误

print ("Fighting, Wuhan! Stay strong, China!")