Week3: cover range - locally greedy

C- interval coverage

Title Description
number line has n (1 <= n <= 25000) a closed interval [ai, bi], selected to cover a range of as little as specified segment [1, t] (1 < = t <= 1,000,000), can not -1 output words do.

Input format
input data comprising a plurality of sets, for each set of data:
first line: n-and t.
The second row to row n + 1: a closed interval each line.

Output Format
For each set of data, the number of the output selection section, the impossible outputs -1.
Each data output on a separate line.

Sample

3 10
1 7
3 6
6 10

2

Warning doline
These sections cover the entire point, i.e., (1,2) + (3,4) may cover (1,4);
But if (1,2) is (4,5), then (2) no cover 3.

Time can be appreciated analogy:
for example comprises a first second [1,2) left and right to open and close time intervals.
Two seconds before and a third and fourth second may cover the entire first four seconds ~

In addition the large amount of data problem, do not use iostream.

Problem-solving ideas
This question sinkhole Cheetos, but there is a time limit (1000ms). He wrote more than ten hours, about 6 version, once the collapse of the mentality to want to give up. The results today opened a new .cpp, re-written from scratch again after a result, it is metaphysics.
I now think it may be my last time with the AC cin instead of scanf is under ios :: sync_with_stdio (false) to change the final outcome. ( Is to blame for the evil compiler )
Miserable
given below WA after 12 AC code and analysis.

See this question, we have taken greedy strategy:
For each test, press a small to large order, the starting point of the interval if greater than 1 s (initial s = 1), no solution; otherwise, select the starting point of the longest interval s . Selection interval [ai, bi] should be set to the starting point bi, bi before and partially cut off.

First, the amount of bulk data is very large, so if you use cin and cout almost certainly will time out (that have proven time out), so here we use scanf or ios :: cin under sync_with_stdio (false).

Then we use a vector array to store the input section, the above-described sort.

Setting a variable len, initial value 0.
We then use a for loop to loop through all sections of the array, for these intervals we have:

  • The current range of b i s less than the current, then choose this certainly is a waste, abandoned, continue.
  • A current i is smaller than or equal interval s + 1 (note), update len. len meaning a less for all s + 1 interval, b is the distance to the maximum distance s, greedy move the core, i.e., for each cover, are selected to cover the widest range of possible that interval, this range can be selected as little as possible.
  • A current greater than the section i s + 1, the selection of this interval will be empty, i.e. not full coverage, against the meaning of problems, since previously been sorted, it does not meet all the following sections, thus break.

After out of the loop, we examined the value of len. If len is 0, the above described three cases, the absence of the second. If only the first and third cases, there will be empty, set of data which description is inconclusive, we -1 output, this set of data processing is terminated.

After processed, we s current move above that the len b at the maximum range. Then the cycle is repeated starting from a series of operations for, until s == t;

Sample Code

#include <iostream>
#include <algorithm>
#include <vector>
const int badans = -1;
using namespace std;

struct TC
{
	int a;
	int b;
};

vector<TC> arr;

bool cmp(const TC& m, const TC& n)
{
	return m.a < n.a;
}

int main()
{
	ios::sync_with_stdio(false);
	int n, s, t;
	while (cin >> n >> t)
	{
		arr.clear();
		s = 0;//因为下面代码中使用s+1来实现整点覆盖,由于s初始值应该是1,所以这里预设为0
		int ans = 0;
		bool isok = true;

		for (int i = 0; i < n; i++)
		{
			TC temTC;
			cin >> temTC.a >> temTC.b;
			arr.push_back(temTC);
		}

		sort(arr.begin(), arr.end(), cmp);

		//一个可选的剪枝
		//如果不用这个,那么nowpos的那个位置恒设为-1,即i=0
		int nowpos = -1;
		while (s < t)
		{
			int len = 0;
			int themaxone = 0;//记录使len最大的那个区间
			for (int i = nowpos + 1; i < arr.size(); i++)
			{
				if (arr[i].b <= s) continue;

				if (arr[i].a <= s + 1)//整点覆盖
				{
					int x = arr[i].b - s;
					if (x > len)
					{
						len = x;
						themaxone = i;
						nowpos = i;
					}
				}
				else break;
			}

			if (len == 0)//无解,直接输出-1并break出循环
			{
				cout << badans << endl;
				isok = false;
				break;
			}

			ans++;
			s = arr[themaxone].b;//刷新当前s
		}
		
		//如果不是通过break跳出循环的话说明是有解的
		if (isok) cout << ans << endl;
	}
	
	return 0;
}
Published 21 original articles · won praise 3 · Views 417

Guess you like

Origin blog.csdn.net/qq_44506233/article/details/104702555