uva10382

18 篇文章 0 订阅
12 篇文章 0 订阅

题目大意:
最少要用多少个给定的圆才能把长度为l,宽度为w的完全覆盖住。

思路:
区间覆盖问题,本来一直WA和TLE,结果现在寒假训练找又做到了,改了一个地方,居然A了。

代码:

#include <iostream>
using namespace std;
#include <cstring>
#include <stdio.h>
#include <cmath>

int N;
double l,w;
struct node {
    double pos;
    double r;
}n[10005];

int main() {

    int count1,index;
    double _max;
    double p,r;
    while(scanf("%d%lf%lf",&N,&l,&w)!= EOF) {
        index = 0;
        count1 = 0;
        _max = 0;
        for(int i = 0; i < N; i++) {
            scanf("%lf %lf",&p,&r);
            if(w/2 >= r)
                continue;
            double t = sqrt(r*r-w*w/4);
            n[index].pos = p-t;
            n[index].r = p+t;
            index++;
        }
        double min = 0,max = 0;
        int rr = 0,pp,t;
        while(1) {
            if(min >= l)
                break;
        //  max = 0;
            rr =0;
            for(int i = 0 ; i < index; i++) {
                if(n[i].pos  <= min && n[i].r > max ) {
                    max =  n[i].r;
                    rr = 1;
                    pp = i;
                }
            }
            if(rr) {
                min = n[pp].r;
                count1++;
            }
            else 
                break;
            }

        if(rr) 
            printf("%d\n",count1);
        else
            printf("%d\n",-1);

    }
    return 0;   
}
#include <iostream>
using namespace std;
#include <cstring>
#include <stdio.h>
#include <cmath>

int N;
double l,w;
struct node {
    double pos;
    double r;
}n[10005];

bool judge(double a,double b,double c) {

//  printf("%d %d %d \n",a,b,c);
//  printf("%lf",(sqrt((a+b+c)*(a+b-c)*(a+c-b)*(b+c-a))/c));
    if(sqrt((a+b+c)*(a+b-c)*(a+c-b)*(b+c-a))/c >=w)
        return true;
    return false;
}
int main() {

    int count1;
    double _max;
    while(scanf("%d%lf%lf",&N,&l,&w)!= EOF) {
        count1 = 0;
        _max = 0;
        for(int i = 0; i < N; i++) {
            scanf("%lf %lf",&n[i].pos,&n[i].r);
            if(n[i].pos + n[i].r > _max)
                _max = n[i].pos + n[i].r;
        }
        if(_max < l) {
            printf("%d\n",-1);
        }
        else {
            double min = 0,max = 0;
            int rr = 0,p,t;
            bool first = true;
        while(1) {
    //      cout << 1;
            if(min >= l)
                break;
            max = 0;
            rr =0;
            for(int i = 0 ; i < N; i++) {
                if(n[i].pos - n[i].r <= min && n[i].pos + n[i].r > max ) {
                if(first){
                //  first = false;
                    max = n[i].pos + n[i].r;
                    rr = 1;
                    p = i;
                }
                else if(judge(n[t].r,n[i].r,n[i].pos-n[t].pos) ) {
                        max = n[i].pos + n[i].r;
                        rr = 1;
                        p = i;
                    }
                }
            }
            if(rr) {
                first = false;
                min = n[p].pos + n[p].r;
                t = p;
                count1++;
            }
            else 
                break;
            }
        if(rr) 
            printf("%d\n",count1);
        else
            printf("%d\n",-1);
        }
    }
    return 0;   
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值