1. 程式人生 > >UVA-10020-貪心

UVA-10020-貪心

  題意:給你一些數軸上的線段,要求尋找出某些線段能夠完全覆蓋[0,M],並且取的線段數目最小.

解題思路:

 貪心思路,

1.每個線段都有一個L和R,代表它的起點和終點,對於所有R <= 0 ,  L>=R的線段全不要,不符合題意.

2.對於每個線段,根據L進行排序,如果L相同,長度長的排前面.

那麼選取的時候只要從原點0開始,每次選取最長的線段即可.

附上一組用例.

3
 
1
-1 0
-5 -3
2 5
0 0

1
-1 0
0 1
0 0 
 

17
0 4
0 1
1 5
4 10
10 13
13 17
5 17
0 0

 

#include <string>
#include<iostream>
#include<map>
#include<memory.h>
#include<vector>
#include<algorithm>
#include<queue>
#include<vector>
#include<stack>
#include<math.h>
#include<iomanip>


namespace cc
{
	using std::cout;
	using std::endl;
	using std::cin;
	using std::map;
	using std::vector;
	using std::string;
	using std::sort;
	using std::priority_queue;
	using std::greater;
	using std::vector;
	using std::swap;
	using std::stack;

	class Point
	{

	public: int l, r, len;
			Point() {};
			Point(int x, int y) :l(x), r(y) {
				if (l < 0)
					this->len = r;
				else
					this->len = r - l; 
			
			};

			int operator < (Point& p)
			{
				int l1 = p.l;
				int l2 = this->l;
				if (l1 < 0)
					l1 = 0;
				if (l2 < 0)
					l2 = 0;
				if (l1 < l2)
					return 0;
				if (l1 == l2)
					return p.len < this->len;
				return 1;
			}

	};

	constexpr int N = 100000;

	int M;
	int ok;
	int ans = 0;
	Point result[N + 1];
	Point input[N + 1];
	int n;

	void init()
	{
		ok = M = ans =n = 0;
	}

	void dump()
	{
		for (int i = 0;i < n;i++)
		{
			cout << input[i].l << " " << input[i].r << endl;
		}
	}

	void search(int curR, int curIndex)
	{
		int curMax = 0;
		int okIndex = -1;
		int endIndex = -1;
		for (int i = curIndex;i < n;i++)
		{
			if ((input[i].l <= curR && input[i].r > curR))
			{
				if (input[i].r > curMax)
				{
					curMax = input[i].r;
					okIndex = i;
					continue;
				}
			}
			if (input[i].l > curR)
			{
				endIndex = i;
				break;
			}
		}
		if (okIndex != -1)
		{
			result[ans++] = input[okIndex];
			if (input[okIndex].r >= M)
			{
				ok = 1;
				return;
			}
			if (endIndex == -1)
				return;
			search(curMax,endIndex);
		}
	}

	void solve()
	{
		int cases;
		cin >> cases;
		int t = 0;
		while (cases--)
		{
			if (t != 0)
				cout << endl;
			t++;
			int l, r;
			init();
			cin >> M;
			while (cin >> l && cin >> r && (l || r))
			{
				if (r <= 0||l >= r)
					continue;
				Point p(l, r);
				input[n++] = p;
			}
			sort(input, input + n);
			//dump();
			search(0,0);
			if (ok)
			{
				cout << ans << endl;
				for (int i = 0;i < ans;i++)
					cout << result[i].l << " " << result[i].r << endl;

			}
			else
			{
				cout << 0 << endl;
			}

		}

	}

};


int main()
{

#ifndef ONLINE_JUDGE
	freopen("d://1.text", "r", stdin);
#endif // !ONLINE_JUDGE
	cc::solve();

	return 0;
}