POJ1328

wa到絕望。。。一開始想錯了思路。從左到右開始移動圓圈然後進行圓圈數目的增加。。嗯。。沒錯。。。。這個是錯的思路。
不信的話試下數據
2 3
0 2
1 3
這個算法算出來是2,然而正確答案是1
正確思路是把各個島看成是雷達,然後與海岸線的交點存儲起來爲一條線段線段,利用線段之間的交集進行圓圈數目的計算。
要注意的是數據需要double。。不然wa到你絕望。而且。。輸入數據要用scanf。。不然tle到你絕望。。。。
**

代碼

**

#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
struct Node
{
	double x, y;
}node[1005], le[1005];
bool cmp(Node a, Node b)
{
	if(a.x == b.x)
		return a.y < b.y;
	return a.x < b.x;
}
int main()
{
	ios::sync_with_stdio(false);//然而這樣寫的話等同於scanf
	cin.tie(NULL);
	cout.tie(NULL);
	int n, count = 1, ans;
	double mid, m, l ,r;
	while(cin >> n >> m)
	{
		if(n == 0 && m == 0)
			break;
		bool flag = false;
		ans = 1;
		for(int i = 0; i < n; i++)
		{
			cin >> node[i].x >> node[i].y;
			if(node[i].y > m)
				flag = true;
		}
		if(flag)
			cout << "Case " << count++ <<": -1" << endl;
		else
		{
			for(int i = 0; i < n; i++)
			{
				mid = sqrt(pow(m, 2) - pow(node[i].y, 2));
				le[i].x = node[i].x - mid, le[i].y = node[i].x + mid; //計算線段的左端點和右端點
			}
			sort(le, le + n, cmp);
			l = le[0].x;
			r = le[0].y;

			for(int i = 1; i < n; i++)
			{
				if(le[i].x > r)  //線段不重合的情況
				{
					r = le[i].y;
					l = le[i].x;
					ans++;
				}
				if(le[i].x > l && le[i].y < r)  //線段包含的情況
				{
					l = le[i].x;
					r = le[i].y;
				}
				if(le[i].x > l && le[i].y > r)  //線段有一些重合的情況
					l = le[i].x;
			}
			cout << "Case " << count++ << ": " << ans << endl;
		}
	}
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章