T-net(贪心)

T-net which is a new telecommunications company, plans to install its base stations in the city. The places where base stations must be installed have been already specified. T-net has two types of antennas to be used in the base stations: (i)antennas with transmission radius a, and (ii) antennas with transmission radius b. Two antennas can communicate with each other if and only if both are inside the coverage area of each other. Antenna with smaller transmission radius of course is cheaper. T-net plans to minimize its cost while keeping the whole network connected. Precisely, T-net plans to
minimize its cost which is the sum of the transmission radii of all antennas. Interestingly, all base-station places are on a line. Help T-net construct a connected network with the minimum cost.

 

输入

The first line of the input contains three positive integers n, a and b (1 ⩽ n ⩽ 105 and 1 ⩽ a, b ⩽ 105 ) where n is the number of base stations, and a and b are radii as defined in the problem statement. The second line contains n distinct coordinates of base stations on the line with respect to an origin on the line. All coordinates are positive integers not more than 105 .

 

输出

If it is possible to construct a connected network, print the minimum cost in the output. Otherwise, print -1 .

思路: 我们先假设每一个站点都安装的半径较小的网络,然后可以判断出哪些站之间用较短网络是无法连接的,把这些站点根据能否连接分块。我们以  
7  1  3
1 3 4 5 7 8 9  为例  分块如下图

T-net(贪心)_第1张图片

而后我们自左向右分块遍历,我们要做的就是实现块与块之间的连接,基本思想是我在上一块站点所建立的网络半径所能达到的最右端的那一个站点建立网络。在此分三种情况:1.上一块站点的网络的半径若能全部覆盖下一块,则在下一块的最末尾站点建立网络2.若只能覆盖一部分,则在所能达到的最右端的那一个站点建立网络。若新建的网络能覆盖下一站点则进入下一块。若完全不能覆盖,则在本块最末端建立网络。再判断是否能覆盖下一站点,若能进入下一块,不能输出-1

下面上代码

# include 
# include 
# include 
# define ll long long
using namespace std;
struct node{
    ll l,r;
    ll l1,r1;
}p[100010];
ll A[100010];
int main(){
    ll n,a,b;
    ll i;
    scanf("%lld%lld%lld",&n,&a,&b);
    if(b>a)
        swap(a,b);
    
    for(i=1;i<=n;i++){
        scanf("%lld",&A[i]);
    }
    if(n==1){
        printf("%lld\n",b);
        return 0;
    }
    sort(A+1,A+1+n);
    ll ans=n*b;
    ll num=0;
    ll k=1;
    for(i=2;i<=n;i++){
        if(num==0){
            p[k].l=A[i-1];
            p[k].l1=i-1;
            num++;
        }
        if(A[i]-A[i-1]>b){
            if(num){
                num=0;
                p[k].r1=i-1;
                p[k++].r=A[i-1];
                p[k].l=A[i];
                p[k].l1=i;
            }
        }
        else{
            num++;
        }
    }
    if(p[k].l){
        p[k].r=A[n];
        p[k].r1=n;
    }
    else{
        k--;
    }
    i=1;
    ll x=p[i].r;
    i++;
    while(i<=k){
        while(i<=k&&p[i].r<=x+a){
            if(i==k){
                ans+=(a-b);
            }
            ans+=(a-b);
            x=p[i].r;
            i++;
        }
        if(i==k+1){
            break;
        }
        if(p[i].l>x+a){
            printf("-1\n");
            return 0;
        }
        else if(x+a>=p[i].l&&x+a

 

你可能感兴趣的:(杂,日常训练)