lightoj 1383 - Underwater Snipers

    PDF (English) Statistics Forum
Time Limit: 4 second(s) Memory Limit: 32 MB

King Motashota is in a war against the mighty Bachchaloks. He has formed a well trained army of snipers, and planning to use them as much as possible. In one of the missions, he has S snipers. They will be dispatched to get rid of the soldiers guarding the bank of the river Nodi.

From satellite images, Motashota has located positions of all enemy soldiers. Now, the plan is, snipers will take their positions. They are excellent swimmers, so, you can assume that they won't get caught, while taking position. Upon order from Motashota, they will start shooting enemy soldiers. A sniper can shoot a soldier, if Euclidean Distance between the soldier and sniper is no more than D. After the snipers get rid of all the soldiers, they can proceed with the operation. So, it is important for them to position the snipers in such a way that, all soldiers are within the range of at least one sniper.

In addition, when snipers start shooting, the guards will be alert, and thus, snipers can't change their position, they can only continue shooting from their position.

The river bank is defined by the horizontal line y = k. All points (x, y) where y > k is in the enemy territory, and if y < k, then it's on the water. You will be given location of N soldiers, strictly in the enemy territory; you have to place S soldiers in the water, so that they can kill all soldiers. For security reasons, the snipers should be as far from the bank as possible. For any sniper in position (xi, yi), the distance from the bank is |yi - k|. If, for all snipers, the minimum of them is M = min{|yi - k|}, you have to maximize M.

Both the soldiers and snipers are really superstitious. They will stay only in integer coordinates.

Input

Input starts with an integer T (≤ 100), denoting the number of test cases.

Each case starts with a black line. Next line contains four integers, k (-108 ≤ k ≤ 108)N (1 ≤ N ≤ 10000)S (1 ≤ S ≤ 10000) and D (1 ≤ D ≤ 109), the position of the bank, number of guards and number of snipers, and the range of the snipers.

This is followed by N lines, each containing a pair of integers (xi, yi) the position of ith guard (-108 ≤ xi ≤ 108, k < yi ≤ 108).

Output

For each case, print the case number and M which is described in the statement. If the snipers cannot kill all the guards, print "impossible".

Sample Input

Output for Sample Input

2

 

0 3 2 4

1 1

3 2

9 1

 

0 3 1 4

1 1

3 2

9 1

Case 1: 2

Case 2: impossible


有个bank,一边是soldier,一边是sniper,每个sniper有个最大射程,问s个sniper把n个soldier杀完最少需要靠近bank多少距离,其实也就是尽可能的离bank远点保证安全。
那么我们就二分到bank的距离就好了。
然后换成区间安排岗哨的问题了。
点击打开链接
/*****************************************
Author      :Crazy_AC(JamesQi)
Time        :2015
File Name   :
*****************************************/
// #pragma comment(linker, "/STACK:1024000000,1024000000")
#include <iostream>
#include <algorithm>
#include <iomanip>
#include <sstream>
#include <string>
#include <stack>
#include <queue>
#include <deque>
#include <vector>
#include <map>
#include <set>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <climits>
using namespace std;
#define MEM(x,y) memset(x, y,sizeof x)
#define pk push_back
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> ii;
const double eps = 1e-10;
const int inf = 1 << 30;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
const int maxn = 10010;
struct Item{
    int l, r;
    bool operator < (const Item& rhs)const{
        return this->r < rhs.r;
    }
}p[maxn], A[maxn];
int k,n,s,d;
bool check(int mid){
    for (int i = 1;i <= n;++i){
        if (p[i].r + mid > d) return false;
        double a = d + (p[i].r + mid);
        double b = d - (p[i].r + mid);
        double l = p[i].l - sqrt(a * b);
        double r = p[i].l + sqrt(a * b);
        A[i].l = (int)ceil(l);
        A[i].r = (int)floor(r);
    }
    sort(A + 1,A + 1 + n);
    int cnt = 0;
    int i = 1;
    while(i <= n){
        int pos = A[i].r;
        cnt++;
        while(i <= n && pos >= A[i].l && pos <= A[i].r)i++;
    }
    return cnt <= s;
}
int main()
{    
    freopen("in.txt","r",stdin);
    // freopen("out.txt","w",stdout);
    int t, icase = 0;
    scanf("%d", &t);
    while(t--){
        scanf("%d%d%d%d",&k,&n,&s,&d);
        for (int i = 1;i <= n;++i){
            scanf("%d%d",&p[i].l, &p[i].r);
            p[i].r -= k;
        }
        int high = d, low = 1;
        int ans;
        bool flag = false;
        while(low <= high){
            int mid = (high + low) / 2;
            if (check(mid)){
                flag = true;
                ans = mid;
                low = mid + 1;
            }else high = mid - 1;
        }
        printf("Case %d: ", ++icase);
        if (flag) printf("%d\n", ans);
        else printf("impossible\n");
    }
    return 0;
}


你可能感兴趣的:(贪心,二分,lightoj)