題目大意:
給定源區間[x, y] (x≤y) 和 n個無序的目標區間[xi, yi](1 ≤ i ≤ n)。
判斷源區間是否在目標區間內。
分析:書中介紹了兩種解法。
第一種:將目標區間投影到源區間,看最終未被覆蓋的區間是否變為。
這種方法的複雜度無疑是很高的。 o(n^2)。
另外,對於k組源區間查詢,其複雜度是單次的k倍。
第二種:"線段樹"
這種解法很好解決了第一種演算法出現的問題。
先將所有n組目標區間按照x排序,並合併為多個小區間。【這些小區間是有序的】
之後對於給定的源區間,基於二分思想定位區間的位置。
複雜度:
目標區間排序:o(n*logn)
排序後目標區間合併:o(n)
源區間一次查詢:o(logn)
因此對於k組源區間查詢
總體複雜度:o(nlogn + klogn)。
大大提高了效率。
下面給出自己實現的**:
【已在vs2013上編譯測試通過】
#include #include #include using namespace std;
typedef pairrange;
bool cmp(const range& a, const range& b)
bool binarysearch(vector&mergerange, range &src)
else if (mergerange[mid].second <= src.first)
else if (mergerange[mid].first >= src.second)
else
}return isfound;
}int main(void)
// 1. 排序目標區間
sort(vrs.begin(), vrs.end(), cmp);
// 2. 合併目標區間
vectormergerange;
vector::iterator it = vrs.begin();
int st = it->first, ed = it->second;
for (; it != vrs.end(); ++it)
ed = ((it + 1)->second > ed) ? (it + 1)->second : ed;
} // 剩下最後乙個區間
else
else
}} cout << "請輸入要查詢的源區間 -1 -1 為結束標誌" << endl;
while (cin >> src.first >> src.second, src.first != -1 && src.second != -1)
else
}return 0;
}
下面給出執行截圖:
對於文中給出的擴充套件問題
改天再更新~
希望大家批評指正~
程式設計之美2 19 區間重合判斷
題目 給定乙個源區間 x,y y x 和n個無序的目標區間 x1,y1 x2,y2 x3,y3 xn,yn 判斷源區間 x,y 是不是在目標區間內?例如,給定源區間 1,6 和一組無序的目標區間 2,3 1,1 3,9 即可認為區間 1,6 在區間 2,3 1,1 3,9 內,因為目標區間實際上是 ...
程式設計之美 2 19 區間重合判斷
給定乙個源區間 x,y y x 和n個無序的目標區間 x1,y1 x2,y2 xn,yn 判斷源區間 x,y 是不是在目標區間內 eg,給定乙個源區間 1,6 和一組無序的目標區間 2,3 1,2 3,9 即可認為 1,6 在區間 2,3 1,2 3,9 內 因為目標區間合併之後,實質為 1,9 i...
程式設計之美2 19區間重合判斷
區間重合判斷 比如,給出待判斷區間 x,y 如 1,6 以及目標區間 x1,y1 x2,y2 xi,yi 如 2,3 1,2 3,9 判斷 1,6 是否在目標區間中 做法 先把根據各個目標區間的第乙個元素xi排序 可用快排 然後將目標區間中可以合併的區間進行合併,然後 在目標區間的xi中用二分查詢來...