提交 c2ddfe24 编写于 作者: F feilong

添加一个题目

上级 27e4f70c
# 查找点在自然区间的坐标
定义:
* 实数轴上的一个区间由左右两个端点,假设区间是左闭右开的,例如区间`[0,1)`
* 给定一个有序的不重合非负整数区间列表 range_list :[ `[0,1)`, `[3,4)` ]
* 该非负整数区间列表将实数轴分割成了这些区间列表 range_list_nature_ext : [`(-∞,0)`,`[0,1)`,`[1,3)`,`[3,4)`,`[4,+∞)`]
* 我们称 range_list_nature_ext 为由 range_list 扩展的 `自然区间`
问题:写一个查找算法,对于给定非负整数区间列表 range_list ,查找一个非负整数 p 落在了 range_list_nature_ext 的那个区间,返回那个区间的在 range_list_nature_ext 里的下标,我们称这个下标为非负整数 p 在 rage_list 里的 `自然坐标`
## 输入描述
第一行输入要查找的非负整数 p,以及区间列表个数 N,用空格分开
第二行到第N+1行输入非负整数区间列表的每个区间,这些区间列表不重叠,按在实数轴上从左到右的顺序挨个输入,区间的两个坐标用空格分开
## 输出描述
输出一行,包含非负整数 p 的自然坐标
## 输入样例
12 2
0 10
15 20
## 输出样例
2
## 提示
#include <stdint.h>
#include <inttypes.h>
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
class Range
{
public:
Range():m_pos(0), m_length(0){};
Range(uint64_t pos, uint64_t length): m_pos(pos), m_length(length){}
Range(Range const & rhs){
if (this == &rhs)
return;
m_pos = rhs.m_pos;
m_length = rhs.m_length;
}
Range& operator = (Range const & rhs){
if (this == &rhs)
return *this;
m_pos = rhs.m_pos;
m_length = rhs.m_length;
return *this;
}
~Range(){}
bool operator<(Range const & rhs) const{
return m_pos < rhs.m_pos || (m_pos == rhs.m_pos && m_length < rhs.m_length);
}
uint64_t GetPos() const {
return m_pos;
}
uint64_t GetLength() const{
return m_length;
}
uint64_t GetRight() const{
return m_pos+m_length;
}
public:
uint64_t m_pos;
uint64_t m_length;
};
size_t findNatureRangeIndex(std::vector<Range>& rangeList, uint64_t point){
size_t n = rangeList.size();
size_t first = 0;
size_t last = 2 * n + 1;
size_t max = last;
uint64_t testBeg = 0;
uint64_t testEnd = 0;
size_t idx = SIZE_MAX;
while (first <= last) {
size_t mid = (first + last) / 2; // compute mid point.
std::cout<<"xx:"<<mid;
// 处理右边界
if (mid >= max - 1) {
uint64_t lastEnd = rangeList[n - 1].m_pos + rangeList[n - 1].m_length;
std::cout<<"point:"<<point<<"lastEnd:"<<lastEnd<<"max:"<<max;
if (point>=lastEnd) {
idx = max - 1;
} else {
idx = max - 2;
}
break;
}
// 处理左边界
if (mid == 0) {
if (point >= rangeList[0].m_pos) {
idx = 1;
} else {
idx = 0;
}
break;
}
// 处理中间
bool even = mid % 2 == 0;
if (even) {
size_t left = (mid - 1) / 2;
size_t right = left + 1;
testBeg = rangeList[left].m_pos + rangeList[left].m_length;
testEnd = rangeList[right].m_pos;
} else {
size_t current = mid / 2;
testBeg = rangeList[current].m_pos;
testEnd = rangeList[current].m_pos + rangeList[current].m_length;
}
// 二分查找
if (point>=testEnd) {
std::cout<<"->"<<point<<","<<testBeg<<","<<testEnd<<std::endl;
first = mid + 1; // repeat search in top half.
} else if (point<testBeg) {
std::cout<<"<-"<<point<<","<<testBeg<<","<<testEnd<<std::endl;
last = mid - 1; // repeat search in bottom half.
} else {
std::cout<<point<<","<<testBeg<<","<<testEnd<<std::endl;
idx = mid;
break;
}
}
std::cout<<std::endl;
return idx;
}
int main(int argc, char** argv){
uint64_t p;
int N;
std::vector<uint64_t> inputs;
// 输入点,区间个数
std::cin>>p;
std::cin>>N;
// 收集区间点
for(int i=0;i<N;i++){
uint64_t l,r;
std::cin>>l;
std::cin>>r;
inputs.push_back(l);
inputs.push_back(r);
}
// 转换区间
std::vector<Range> rangeList;
for(int i=0;i<inputs.size();i+=2){
Range range(inputs[i],inputs[i+1]-inputs[i]);
rangeList.push_back(range);
}
// 查找
size_t pos = findNatureRangeIndex(rangeList, p);
std::cout<<pos;
return 0;
}
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册