/* 求2有序N长数组,第K大的数 */ #include <stdio.h> #include <iostream> #include <assert.h> #include <algorithm> #define min(x,y) (x)<(y) ? (x) : (y) #define max(x,y) (x)>(y) ? (x) : (y) const int N = 4; using namespace std; //方法一 注意 第K大,还有2个边际 int FindKth(int A[], int B[], int n, int low ,int high, int k) { int m=(low+high)/2+1; if(low>high) return '\0'; if(k==m) { return A[m-1]<=B[0] ? A[m-1] : FindKth(A, B, n, low, m-2, k); } else if(k==(N+m)) { return A[m-1]>=B[N-1] ? A[m-1] : FindKth(A, B, n, m, high, k); } else if(k<m+1) return FindKth(A, B, n, low, high-1, k); else if(k>N+m) return FindKth(A, B, n, low+1, high, k); else if (A[m-1]>B[k-m-1] && A[m-1]<B[k-m] ) { return A[m-1]; } else if(A[m-1]>B[k-m]) { return FindKth(A,B,n,low ,m-2, k); } else return FindKth(A, B, n, m, high, k); } int Find_Kth_IN_Arrays(int A[], int B[], int n, int k) { int value=FindKth(A, B, n, 0, n-1, k); if(value=='\0') value=FindKth(B, A, n, 0, n-1, k); return value; } //方法二, int FindKthElement(int a[], int b[], int k) { if(k == 1) return min(a[0], b[0]); else if(k == N * 2) return max(a[N - 1], b[N - 1]); int left = max(k - N - 1, 0), right = N - 1; while(left <= right) { int mid = (left + right) / 2; if(mid + 1 == k) { if(a[mid] < b[0]) return a[mid]; else right = mid - 1; } else if(mid + 1 + N == k) { if(a[mid] > b[k - mid - 2]) return a[mid]; else left = mid + 1; } else { if(a[mid] > b[k - mid - 2] && a[mid] < b[k - mid - 1]) return a[mid]; else if(a[mid] > b[k - mid - 2] && a[mid] > b[k - mid - 1]) right = mid - 1; else left = mid + 1; } } return FindKthElement(b, a, k); } int main() { int K; int a[] = {1, 3, 7, 8}; int b[] = {2, 4 , 5, 6}; while(cin >> K) { assert(K >= 1 && K <= N * 2); cout << FindKthElement(a, b, K) << endl; cout<<Find_Kth_IN_Arrays(a, b, 4, K)<<endl; } return 0; }