在拿到选择不相交区间这个问题的时候,我的第一个想法是不知道如何量化这个问题,或者说不知道如何具体地展开成一种计算问题,有n个开区间就有n+1个点,而且是开区间,相邻区间不会相交,那么只需要将数轴上的所有的点升序排序并且取临点相取不就好了吗?
但是知道读到分析之后才明白,原来这个问题的区间是已经划分好了的,是取这些区间的时候不能取到相交区间。
数轴区间就必然会有顺序问题,所以一定会用到排序。简单的画一个数轴,会想到这个问题大概率不是一个只有一个解的问题。所以我觉得会用到的分析法去以一种排序来分析所有的可能情况。
那么是排序区间前端点还是排序后端点呢?
先分析排序前端点,排序的时候a1和aj很可能是一个点,那么在排序的时候就会有一些大小相同点排序在一起,我们将这些点逐一比较其后端点看那个后端点更小一些,同样的以此类推知道将每个前端点都遍历完成,如何分析相交的问题呢?好像分析成了一团浆糊。
以前高中的时候做题就是这个样子,分析到一定程度就分析不下去了,但是觉得之前分析的还是挺有道理的,所以有很多时候就会在分析不下去的地方徘徊不去另想新的方法。
那么我现在讲排序换成排序后端点,但是我觉得将后端点从大大小排,那么前端点取得越大越好,那又怎么防止相交呢?又不会了,再读一行分析发现,题意是这些区间可以自己去标定顺序,这也是读不懂题目的一大原因。
数轴上有n个开区间,那在读取的时候你肯定要为这些区间自己去标定哪个区间是哪个吧? 可以用vector 里面放着类型的pair数据,我们以pair的后一个元素的大小来排序这个vector 利用sort算法的三参数形式。
这样一来,任何在a1左端的前端点ai所在的区间是绝对不选的, 只有在a1右端的ai是值得考虑的,这样因为a1是第一截,出去刚开始的独立单元外,他总是被包含在其他截中,所以a1必选。所以任何 大于a1小于b1的前端点都不可以被选,任何前端点小于a1的也不可以被选择 那么在碰到第一个不满足这个条件的点的时候,就作为新的a1,其也将被必选,直至所有的区间被遍历完成,完成整个选择过程。
bool comp(const pair<int, int> a, const pair<int , int> b)
{
return a.second < b.second;
}
int main()
{
cout << "please input the blocks" << endl;
vector<pair<int, int > > vec;
vector<pair<int, int> > vec_selected;
int n(0);
int fir(0);
int sec(0);
pair<int, int> ipair;
while (cin >> fir >> sec)
{
ipair.first = fir;
ipair.second = sec;
vec.push_back(ipair);
n++;
}
sort(vec.begin(), vec.end(), comp);
vec_selected.push_back(vec.at(0));
for (int i(0); i < n; ++i)
{
for (int j = i + 1; j < n; ++j)
if (vec.at(j).first >= vec.at(i).second)
{
vec_selected.push_back(vec.at(j));
i = j-1;
break;
}
}
for (vector<pair<int, int > >::iterator iter(vec_selected.begin()); iter != vec_selected.end(); iter++)
{
cout << "( "<< iter ->first << ", " << iter->second << " )" << endl;
}
}