pat甲 1029
开始以为时间限制比较紧,所以用二分实现的,O(logN logN)。
比较复杂,且只能确定大概位置,最后还要写一个小模拟。
模拟的特判不好写,容易漏掉情况。
想想有没有别的办法完成这个特判。
1 #include <bits/stdc++.h>
2 #define ll long long
3
4 using namespace std;
5 const int maxn = 2e5+10;
6 int la, lb;
7 ll a[maxn], b[maxn];
8
9 int main()
10 {
11 while(scanf("%d", &la) != EOF) {
12 for(int i = 0; i < la; i++)
13 scanf("%lld", &a[i]);
14 scanf("%d", &lb);
15 for(int i = 0; i < lb; i++)
16 scanf("%lld", &b[i]);
17 if(b[lb-1] > a[la-1]) {
18 swap(a, b);
19 swap(la, lb);
20 }
21 int l = 0, r = la-1, mid, pos;
22 while(l < r) {
23 mid = (l+r)>>1;
24 pos = lower_bound(b, b+lb, a[mid])-b;
25 // printf("%d %d %d %d\n", l, r, mid, pos);
26 if((mid+1+pos)*2 <= la+lb)
27 l = mid+1;
28 else
29 r = mid;
30 }
31 pos = lower_bound(b, b+lb, a[l])-b;
32 // printf("%d %d\n", l, pos);
33 while(l>-1 && pos && l+1+pos != la+lb-(la+lb)/2) {
34 if(a[l] >= b[pos-1]) l--;
35 else pos--;
36 }
37 while(l > -1 && l+1+pos != la+lb-(la+lb)/2) l--;
38 while(pos && l+1+pos != la+lb-(la+lb)/2) pos--;
39 // printf("%lld %lld\n", a[l], b[pos-1]);
40 if(l > -1 && pos) printf("%lld\n", max(a[l], b[pos-1]));
41 else if(pos) printf("%lld\n", b[pos-1]);
42 else if(l > -1) printf("%lld\n", a[l]);
43 }
44 return 0;
45 }
46
47 /*
48
49 3 4 5 6
50 1 9
51
52 */
后来看别人题解,发现可以用O(N)算法。
利用的归并排序中的合并两个数组思想。
1 #include <bits/stdc++.h> 2 #define ll long long 3 using namespace std; 4 const int maxn = 2e5+10; 5 int n, m; 6 ll a[maxn], b[maxn]; 7 8 int main() { 9 scanf("%d", &n); 10 for(int i = 0; i < n; i++) 11 scanf("%lld", &a[i]); 12 scanf("%d", &m); 13 for(int i = 0; i < m; i++) 14 scanf("%lld", &b[i]); 15 int num = (n+m+1)>>1, cnt = 0, l = 0, r = 0; 16 ll ans; 17 while(l < n && r < m && l+r < num) 18 ans = a[l] > b[r]? b[r++]:a[l++]; 19 if(l+r < num && l < n) ans = a[l-1+num-l-r]; 20 if(l+r < num && r < m) ans = b[r-1+num-l-r]; 21 printf("%lld\n", ans); 22 return 0; 23 }