zoukankan      html  css  js  c++  java
  • poj3072 Robot ***

    /*
    * Graph-poj-3072.cpp
    *
    * Created on: 2011-11-20
    *
    * dijkstra..
    *
    * 分别用 STL 的 heap操作 和 普通的数组操作 实现
    *
    *
    */
    #include <cstdio>
    #include <cmath>
    #include <cstring>
    using namespace std;

    const int maxn = 20 + 2;
    const double pi = atan(1.0) * 4;
    const double eps = 1e-9;
    const double inf = 100000000;
    int r, n;
    bool vis[maxn] = {};

    struct SNode{
    int x, y;
    double degree;
    double dist;
    };
    SNode node[maxn];

    //两点连线和x轴的夹角
    double getDegree(SNode *cur, SNode *next){
    int tmpx = next->x - cur->x;
    int tmpy = next->y - cur->y;
    double degree = atan2((double)tmpy, (double)tmpx);

    // if(degree < -eps) degree += 2 * pi; //化为[0..2*pi]...这里可写可不写。

    return degree;
    }

    //从cur点的当前方向转到next点的角度, 注意不超过 pi
    double rotateDegree(SNode *cur, SNode *next, double &degree){
    double nextDegree = getDegree(cur, next);
    degree = nextDegree;

    double ans = fabs(nextDegree - cur->degree);
    if(ans > pi + eps) ans = 2 * pi - ans;

    return ans;
    }

    //初始化
    void ini(){
    memset(vis, 0, sizeof(vis));

    for(int i=0; i<n; i++){
    node[i].dist = inf;
    }
    node[0].dist = 0;
    node[0].degree = getDegree(&node[0], &node[n-1]);
    }

    //更新个点的dist域和degree域
    void update(SNode *cur, SNode *next){
    double dist;
    double tmpDist = sqrt(fabs((cur->x - next->x) * (cur->x - next->x)*1.0
    + (cur->y - next->y) * (cur->y - next->y)*1.0));

    //超过r
    if(tmpDist > r + eps)
    return;

    //
    double tmpDegree;
    //距离,注意角度化为 °
    dist = rotateDegree(cur, next, tmpDegree) * 180 / pi + tmpDist + cur->dist;
    if(dist < next->dist - eps){
    next->dist = dist;
    next->degree = tmpDegree;
    }
    }


    void dijkstra(){
    double min = inf;
    int cur = -1;

    ini();

    while(!vis[n-1]){
    //找到当前最小距离的点
    cur = -1, min = inf;
    for(int i=0; i<n; i++){
    if(!vis[i] && node[i].dist < min - eps){
    min = node[i].dist;
    cur = i;
    }
    }
    //更新完了
    if(cur == -1) break;

    vis[cur] = true;

    //更新
    for(int i=0; i<n; i++){
    if(vis[i]) continue;
    update(&node[cur], &node[i]);
    }
    }


    //结果
    if(!vis[n-1])
    printf("impossible\n");
    else
    printf("%d\n", (int)(node[n-1].dist + 0.5));

    }



    int main(){
    while(scanf("%d%d", &r, &n)){
    if(r == -1) return 0;

    for(int i=0; i<n; i++){
    scanf("%d%d", &node[i].x, &node[i].y);
    }

    dijkstra();
    }

    return 0;
    }

      

      

    //用 STL 的 heap

      

    /*
    * Graph-poj-3072.cpp
    *
    * Created on: 2011-11-20
    */
    #include <cstdio>
    #include <cmath>
    #include <vector>
    #include <algorithm>
    using namespace std;

    const int maxn = 20 + 2;
    const double pi = atan(1.0) * 4;
    const double eps = 1e-9;
    const double inf = 100000000;
    int r, n;

    struct SNode{
    int x, y;
    double degree;
    double dist;
    };
    SNode node[maxn];


    //实现最小堆
    bool cmp(SNode *lhs, SNode *rhs){
    return lhs->dist > (rhs->dist + eps);
    }

    double getDegree(SNode *cur, SNode *next){
    int tmpx = next->x - cur->x;
    int tmpy = next->y - cur->y;
    double degree = atan2((double)tmpy, (double)tmpx);
    // if(degree < -eps) degree += 2 * pi;

    return degree;
    }


    double rotateDegree(SNode *cur, SNode *next, double &degree){
    double nextDegree = getDegree(cur, next);
    degree = nextDegree;

    double ans = fabs(nextDegree - cur->degree);
    if(ans > pi + eps) ans = 2 * pi - ans;

    return ans;
    }

    void ini(vector<SNode *> &v){
    for(int i=0; i<n; i++){
    node[i].dist = inf;
    v.push_back(&node[i]);
    }
    node[0].dist = 0;
    node[0].degree = getDegree(&node[0], &node[n-1]);

    make_heap(v.begin(), v.end(), cmp);
    }

    bool update(SNode *cur, SNode *next){
    double dist;
    double tmpDist = sqrt(fabs((double)(cur->x - next->x) * (cur->x - next->x)
    + (cur->y - next->y) * (cur->y - next->y)));

    if(tmpDist > r + eps)
    return false;

    bool flag = 0;
    double tmpDegree;
    dist = rotateDegree(cur, next, tmpDegree) * 180 / pi + tmpDist + cur->dist;
    if(dist < next->dist - eps){
    next->dist = dist;
    next->degree = tmpDegree;
    flag = 1;
    }
    return flag;
    }

    void dijkstra(){
    vector<SNode *> v;
    vector<SNode *>::iterator iter;
    ini(v);

    SNode *cur;
    while(!v.empty()){
    pop_heap(v.begin(), v.end(), cmp);
    cur = v.back();

    //何时退出循环。。。 这里WA了无数遍。。 囧
    if(cur->dist >= inf - eps) break;

    v.pop_back();

    for(iter=v.begin(); iter!=v.end(); iter++){
    update(cur, *iter);
    }
    //因为UPDATE了数据, 所以要重新建堆 (所以用heap操作慢一些。。 不如直接用数组)
    make_heap(v.begin(), v.end(), cmp);
    }


    if(node[n-1].dist >= inf - eps)
    printf("impossible\n");
    else
    printf("%d\n", (int)(node[n-1].dist + 0.5));

    }



    int main(){
    while(scanf("%d%d", &r, &n)){
    if(r == -1) return 0;

    for(int i=0; i<n; i++){
    scanf("%d%d", &node[i].x, &node[i].y);
    }

    dijkstra();
    }

    return 0;
    }



      

  • 相关阅读:
    Windows Phone 的控件倾斜效果
    在framework4.0 3.5中反序列化 解析JSON
    PhpStorm2.0、3.0,5.0注册码到2112年
    Windows Phone(wp7)系统长按的秘密
    配置ethereal编译环境
    复习C++:引用的一些用法
    转载
    Stay hungry,Stay foolish
    C++:继承的一点注意事项
    纯虚函数
  • 原文地址:https://www.cnblogs.com/longdouhzt/p/2255998.html
Copyright © 2011-2022 走看看