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;
}