1443C. The Delivery Dilemma
binary search/greedy/sortings, 1400, https://codeforces.com/problemset/problem/1443/C
Petya is preparing for his birthday. He decided that there would be nn different dishes on the dinner table, numbered from 1 to n. Since Petya doesn't like to cook, he wants to order these dishes in restaurants.
Unfortunately, all dishes are prepared in different restaurants and therefore Petya needs to pick up his orders from nn different places. To speed up this process, he wants to order courier delivery at some restaurants. Thus, for each dish, there are two options for Petya how he can get it:
- the dish will be delivered by a courier from the restaurant
, in this case the courier will arrive in minutes, - Petya goes to the restaurant
on his own and picks up the dish, he will spend minutes on this.
Each restaurant has its own couriers and they start delivering the order at the moment Petya leaves the house. In other words, all couriers work in parallel. Petya must visit all restaurants in which he has not chosen delivery, he does this consistently.
For example, if Petya wants to order n=4 dishes and a=[3,7,4,5], and b=[2,1,2,4], then he can order delivery from the first and the fourth restaurant, and go to the second and third on your own. Then the courier of the first restaurant will bring the order in 3 minutes, the courier of the fourth restaurant will bring the order in 5 minutes, and Petya will pick up the remaining dishes in 1+2=3 minutes. Thus, in 5 minutes all the dishes will be at Petya's house.
Find the minimum time after which all the dishes can be at Petya's home.
Input
The first line contains one positive integer t (1≤t≤2⋅10^5^) — the number of test cases. Then tt test cases follow.
Each test case begins with a line containing one integer n (1≤n≤2⋅10^5^) — the number of dishes that Petya wants to order.
The second line of each test case contains n integers a~1~…a~n~ (1≤a~i~≤10^9^) — the time of courier delivery of the dish with the number i.
The third line of each test case contains n integers b~1~…b~n~ (1≤bi≤10^9^) — the time during which Petya will pick up the dish with the number i.
The sum of nn over all test cases does not exceed 2⋅10^5^.
Output
For each test case output one integer — the minimum time after which all dishes can be at Petya's home.
Example
input
4
4
3 7 4 5
2 1 2 4
4
1 2 3 4
3 3 3 3
2
1 2
10 10
2
10 10
1 2output
5
3
2
3【张聪,2020年秋】由于 delivery是并行的,pick 是串行的,很自然地想到 delivery 应该优先。所以构建二维数组并对其根据 delivery 时间排序,然后用 greedy 算法思想,找到最小的并行时间,要求其能够覆盖delivery 时间更长的 dish 的串行时间之和。
【施惟明,2020年秋】1)听闻此题 TLE 主要来源于读入数据的耗时,便考虑采用空间换时间的策略,先一波读入所有数据,再进行处理。2)处理部分仍然是 greedy,尽量自己取耗时长的外卖,当自己取的时长和外卖送到的最慢时长相等时为最佳。复杂度 O(nlogn)(上一次好像忘记考虑 sort 的复杂度了...)。
【成泽凯,2020年秋】首先将每个菜的配送用时a~i~和自取用时b~i~配对,然后按配送用时a~i~降序排。因为配送时每个餐馆同时送,所以实际上配送用时短的会被配送用时长的覆盖掉。从前向后遍历,并求自取用时的前缀和 sum[j],当自取用时的前缀和比配送用时 a~j~ 大。
(某同学感谢:由于 Test9 有 200000 个输入,所以一个一个输出处理会超时,经施惟明,成泽恺等同学提醒后,修改了Python代码,使得只输出一次,成功 AC 了。)
【王君宇,2020年秋】当我写完高数作业看群,群里的大佬说 python常规方法可以 AC !!我们平时做这种多组 test问题都是直接循环每次 print,但是也可以将每次结果存到一个列表中,最后一起 print,这样能大大加快速度。确实我对于 python 中各个函数的运行速度还不够了解,这道题锻炼了我的程序思维,更让我加深了对 print 函数的理解。当我看到自己的代码 AC 的那一刻,这个下午的失败值得了!!!
n = int(input())
ans = []
for i in range(n):
m = int(input())
a = list(map(int,input().split()))
b = list(map(int,input().split()))
c = sorted(list(zip(a,b)),reverse=True)
d=0
for i in range(m):
d += c[i][1]
if d >= c[i][0]:
d = max(c[i][0],d-c[i][1])
break
ans.append(d)
print('\n'.join(map(str, ans)))1443C. 整体输出,相当于利用了output buffer。print()函数每次执行会清空buffer,相当于disable buffer,所以慢。 What Is Python Output Buffering and How to Disable It? https://blog.finxter.com/what-is-python-output-buffering-and-how-to-disable-it/
T = int(input())
to_print = []
while T:
T -= 1
n = int(input())
a = [int(x) for x in input().split()]
b = [int(x) for x in input().split()]
if n==1:
to_print.append( min(a[0], b[0]) )
#print(min(a[0], b[0]))
continue
ab = list(zip(a,b))
ab.sort()
k = n - 1
suffix_sum = 0
while suffix_sum <= ab[k][0] and k>=0:
suffix_sum += ab[k][1]
k -= 1
#print( min(ab[k+1][0], suffix_sum))
to_print.append( ( min(ab[k+1][0], suffix_sum)) )
else:
print('\n'.join(map(str, to_print)))T = int(input())
to_print = []
while T:
T -= 1
n = int(input())
a = [int(x) for x in input().split()]
b = [int(x) for x in input().split()]
if n==1:
#print(min(a[0], b[0]))
to_print.append( min(a[0], b[0]) )
continue
ab = list(zip(a,b))
ab.sort( key = lambda x: (-x[0], x[1]))
for i in range(1, n):
ab[i] = ab[i][0], (ab[i][1]+ab[i-1][1])
#print(ab)
#print( max ( map(min, ab) ) )
to_print.append( max ( map(min, ab) ) )
else:
print('\n'.join(map(str, to_print)))【许浩哲,2020年秋】1443C 可以用Python AC的另外一种方法。就是把nput换成sys.stdin.readline,把print换成sys.stdout.write。https://codeforces.com/problemset/problem/1443/C
import sys
n = int(input())
#n = int(sys.stdin.readline())
#ans = []
for i in range(n):
#m = int(input())
m = int(sys.stdin.readline())
a = list(map(int,sys.stdin.readline().split()))
b = list(map(int,sys.stdin.readline().split()))
c = sorted(list(zip(a,b)),reverse=True)
d=0
for i in range(m):
d += c[i][1]
if d >= c[i][0]:
d = max(c[i][0],d-c[i][1])
break
sys.stdout.write('{}\n'.format(d))
#ans.append(d)
#print('\n'.join(map(str, ans)))GNU C++17 Accepted
#include <bits/stdc++.h>
using namespace std;
pair <int,int> a[200001];
int main(){
int t;
cin >> t;
while(t--){
int n;
cin>>n;
int k=0,sum=0;
for(k=1;k<=n;k++)cin>>a[k].first;
for(k=1;k<=n;k++)cin>>a[k].second;
sort(a+1,a+n+1);
k=n;
while(sum<=a[k].first &&k >=1){
sum += a[k].second;
k--;
}
cout << min(a[k+1].first, sum) << endl;
}
return 0;
}