上次整理完在牛客网的输入输出之后,在赛码网却栽了根头。
因此今天再次整理下赛码网中的输入输出类型,并与在牛客网中的输入输出做对比。
思路:如果遇到测试组数不固定的情况,则应该想到使用while True:
命令。对于每组测试数据,都进行一次输出。如果知道了测试组数T,则使用代码行for i in range(T):
。
while True:
n, m = map(int, input().split())
a = [int(c) for c in input().split()]
b = [int(d) for d in input().split()]
c = list(set(a + b))
c.sort()
for i in range(len(c)):
print(c[i])
坑:输出必须得用空格隔开。
修改后的代码:可输出正确答案。
while True:
n, m = map(int, input().split())
a = [int(c) for c in input().split()]
b = [int(d) for d in input().split()]
c = list(set(a + b))
c.sort()
for i in range(len(c)):
print(c[i], end=' ')
还是上面的正确代码,我们来看下。
看到这里我也是震惊了。后面找官网解释说明,才发现人家确实已经早说好了,只是我们没有注意。
赛码网太恶心了。对于用惯了pycharm的用户来说是真的头痛。
while True:
N, M = map(int, input().split())
a = []
b = set()
b.add(1)
for _ in range(M):#将所有关系都添加到列表a中去
a.append(list(map(int, input().split())))
for i in range(M):#如果关系中的第一个元素或第二个元素存在于b中,则小赛的老乡找到了
if (a[i][0] in b or a[i][1] in b) and a[i][2] == 1:
b.add(a[i][0])
b.add(a[i][1])
print(len(b) - 1)
这是我自己写的代码。然鹅只有50%的通过率。
再看下最高赞正确答案:
while 1:
N, M = map(int, input().split())
res = []
for i in range(M):
a, b, c = map(int, input().split())
if c == 1:
r = [a, b] if a < b else [b, a]
res.append(r)
s = set()
s.add(1)
res.sort()
for i in res:
if i[0] in s:
s.add(i[1])
print(len(s) - 1)
对比了下我的答案和正确答案,想了半天就是想不出来我的为啥会只有50%的通过率。难道是因为要考虑边界条件吗?但是我也没发现正确答案里有考虑任何边界条件啊。醉了。
最后我试了一个测试用例:
5 3
1 4 1
2 4 1
3 4 1
答案输出应该是多少?明显是3吧。我的程序输出是3,标准答案输出是1。很明显,我的答案才是完全正确的!!!垃圾赛码网。
别急,到这里我终于又发现我的代码的问题了。我代码的问题在于,看个例子就知道了。
输入
5 3
2 4 1
1 4 1
2 3 1
答案该输出3的。我的代码只输出1。因为按顺序遍历时,我的代码跳过了第一组2和4的关系。
修改一下就好了
while True:
N, M = map(int, input().split())
a = []
b = set()
for _ in range(M):
a = list(map(int, input().split()))
if a[2] == 1:
b.add(a[0])
b.add(a[1])
if 1 in b:
print(len(b) - 1)
else:
print(0)
到这里,我的代码能解决所有的情况和问题。感觉该是最完美的答案了。不服来测。
n = int(input())
cor = []
for i in range(n):
a, b = map(int, input().split())
cor.append([a, a + b])
cor.sort(key=lambda x: x[1]) # cor中存储所有卡车的起始坐标和末尾坐标
start = cor[0][1]
count = 0 # 所需炮弹数量
ans = [] # 建立一个存放每颗炮弹干掉的卡车数量的列表
for res in cor:#贪心算法,参考leetcode引爆气球题
if res[0] > start:
start = res[1]
ans.append(count)
count = 1
else:
count += 1
ans.append(count)
ans.sort()
if len(ans) == 1:
print(max(ans))
else:
print(ans[-1] + ans[-2])
这是我的答案,利用贪心算法解决。然鹅通过率只有20%。
这里为什么要讲下这种类型呢,不是和第二种情况类似吗?
我在笔试时遇到的一个坑主要是,我将多行输入申请添加到一起时,它提示我使用for循环存放多行输入会引起内存超限???不知道有没有和我一样经历的?平时练习还好好的,一到笔试就这样,垃圾赛码网。
找bug要找到死。我这么一个完美的算法,竟然只有20的通过率。题目的答案区还没有python选项的答案。审题已经审了n遍了,也没发现问题。想不出来到底问题出在哪。杀了我算了。垃圾赛码网。
想到了再更吧,垃圾赛码网。
发布之后就想到了哪里错了。
找到了一位大神的思路,参考了下,找到了解决方法。链接: link.
所以我们修改下我们的代码。
n = int(input())
cor = []
for i in range(n):
a, b = map(int, input().split())
cor.append([a, a + b])
cor.sort(key=lambda x: x[1]) # cor中存储所有卡车的起始坐标和末尾坐标
ans = [] # 建立一个存放每颗炮弹干掉的卡车数量的列表
k = 0
while (k < n):#思路在于求出遍历所有卡车,单独发射一颗炮弹时能击穿的最大卡车数
start = cor[k][1]
count = 0
for res in cor:
if res[0] < start:
count += 1
ans.append(count)
k += 1
ans.sort()
if len(ans) == 1:
print(max(ans))
else:
print(ans[-1] + ans[-2])
然鹅通过变为了0。后面一想就明白了,每颗炮弹能击穿的最大卡车数肯定是有重叠的。
那该怎么办呢?
思路转变为,先求出第一颗炮弹能击穿的最大卡车数,然后将这些卡车坐标移除,再求出第二课炮弹的能击穿的最大卡车数,这样就可以了。修改后的代码如下:
def fun(cor): # 函数的作用是返回一颗炮弹能击穿的最大的卡车数量,并且返回炮弹坐标,炮弹坐标想一下就会明白
k = 0
max_num = 0
ans = []
while (k < len(cor)):
start = cor[k][1]
count = 0
for res in cor:
if res[0] <= start <= res[1]:
count += 1
if count > max_num:
max_num = count
ans = [max_num, start] # ans1最后得到的值是一颗炮弹能击穿的最大卡车数,start为这颗炮弹的坐标
k += 1
return ans
n = int(input())
cor = []
for i in range(n):
a, b = map(int, input().split())
cor.append([a, a + b])
cor.sort(key=lambda x: x[1]) # cor中存储所有卡车的起始坐标和末尾坐标
ans1 = fun(cor) # ans1=[max_num,start]max_num代表第一课炮弹能击穿的最大卡车数,start代表第一课炮弹的位置
cor2 = []
for res in cor: # 将第一课炮弹所能击穿的最大卡车的数量中的卡车位置都移除,后面再次求第二颗炮弹能打穿的最大数量
if res[0] > ans1[1] or res[1] < ans1[1]:
cor2.append(res) # 经过这步循环操作之后,cor中移除了第一课炮弹击穿的卡车的坐标
ans2 = fun(cor2)
print(ans1[0] + ans2[0])
经过这一步,通过率变为了70%。真是可喜可贺。自己太垃圾了。然而这样做,还是求得是局部最优值。
举个例子。
这种情况明显代码会输出5,然而实际是6.这说明垃圾贪心算法并不适用。老老实实暴力破解吧。
暴力思路:将每辆卡车的尾坐标视为一个炮弹位置。
def fun(cor, x1, x2): # 函数的作用是返回两颗炮弹能击穿的最大的卡车数量
count = 0
for res in cor:
if res[0] <= x1 <= res[1] or res[0] <= x2 <= res[1]:
count += 1
return count
n = int(input())
cor = []
cor2 = []
for i in range(n):
a, b = map(int, input().split())
cor.append([a, a + b])
cor2.append(a + b)
cor.sort(key=lambda x: x[1]) # cor中存储所有卡车的起始坐标和末尾坐标
cor2.sort()
max_num = 0
for i in range(n):#两重循环遍历两颗炮弹的所有可能组合
for j in range(i + 1, n):
count = fun(cor, cor2[i], cor2[j])
if count > max_num:
max_num = count
print(max_num)
终于100AC通过了。
这道题也是醉了,开始以为用贪心,后面以为得放弃贪心用动态规划,最后发现是暴力解法。
部分参考代码来自赛码网,所有连接也已给出。如有异议联系本人修改或删除。