寻宝问题

琼斯博士在寻宝的过程中,来到了一个平面图呈矩形的封闭房间。
矩形的宽度为w,高度为h。为方便描述,我们将矩形左上角坐标定为(0, 0),右下角坐标定为(w, h)。
房间的入口在矩形上沿的中点(即(w/2, 0)),出口在矩形下沿的中点(即(w/2, h))。狡猾的魔王还放置了许多红外探测器,一旦进入探测器的探测半径以内,将触发警报。

现在琼斯博士向您求助,他能否全身而退不惊动魔王?

输入:boolean escape(int w, int h, int n, double[] x, double[] y, double[] r)
w为矩形宽度,h为矩形高度,n为探测器总数。第i个探测器的坐标为(x[i],y[i]),探测半径为r[i]。

void dfs_visit(vector<vector<int >> &graph, vector<int> &visited, int u){
    for(int i=0;i<graph[u].size();i++){
        if(visited[graph[u][i]]==0){
            dfs_visit(graph, visited,graph[u][i]);
        }
    }
    visited[u]=1;
}
double distance(double x1, double y1, double x2, double y2){
    return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}

bool escape(int w, int h, int n, double x[], double y[], double r[]){
    /*check if the the enternce or exit is in a sensor circle*/
    for(int i=0;i<n;i++){
        if(distance(x[i],y[i],w/2,0)<=r[i] || distance(x[i],y[i],w/2,h)<=r[i])
        return false ;
    }
                
    vector< int> spoints;
    vector< int> epoints;
    for(int i=0;i<n;i++){
                                 /*the sensor which x is small than w/2 and intersect with the rectangle can be a start pointer*/
        if(x[i]<w/2){
            if(abs(y[i])<=r[i] || abs(x[i])<=r[i] || abs(h-y[i])<=r[i]){
                spoints.push_back(i);
            }
        }
        else{
                                                 /*the sensor which x is big than w/2 and intersect with the rectangle can be a end pointer*/
            if(abs(y[i])<=r[i] || abs(w-x[i])<=r[i] || abs(h-y[i])<=r[i]){
                epoints.push_back(i);
            }   
        }
    }
    vector<vector< int>> graph(n);
    vector< int> visited(n);
    if(spoints.size()!=0 && epoints.size()!=0){
                                 /*creat a graph. if the two sensors'circle intersect, add an edge in the graph */
        for(int i=0;i<n;i++){
            for(int j=i+1;j<n;j++){
                if(distance(x[i],y[i],x[j],y[j])<=r[i]+r[j]){
                    graph[i].push_back(j);
                }
            }
        }
                                 /*depth first search the graph by the start pointers, record all the pointers searched in the visited array*/
        for(int i=0;i<spoints.size();i++){
            if(visited[spoints[i]]==0){
                dfs_visit(graph, visited,spoints[i]);
            }
        }
                                 /*check if any of the end pointers is in the visited array, if yes, return false*/
        for(int i=0;i<epoints.size();i++){
            if(visited[epoints[i]]==1){
                return false ;
            }
        }
        return true ;
    }
    else{
        return true ;
    }
}


评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值