加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

UVA 11928 D The Busy Dog

(2011-03-01 16:26:04)
标签:

uva

11928

d

the

busy

dog

it

分类: 计算几何
题目描述:
一条狗被拴在一个杆子上,告诉你杆子的坐标。
然后告诉你n个点,狗依次走到1, 2, 3, ... n, 1各个点的位置,问你绑狗的绳子一共缠了杆子几圈。
解题报告:
模拟即可,计算前后两点的角度差,累加起来,最后除以2π就好了。
比如狗从i点走到i + 1点,设起点为S,那么用余弦定理计算三角形S,i,i+1三角形中S的角度值。
累加起来即可。
题目还让判断过程中是否撞到杆子,判断点与线段相交即可,不再赘述。
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
using namespace std;
#define eps 1e-8
struct pint
{
    double x, y;
}jeo[20000], s;
double dis(int i)
{
    return (jeo[i].x - s.x) * (jeo[i].x - s.x) + (jeo[i].y - s.y) * (jeo[i].y - s.y);
}
double dis2(int i, int j)
{
    return (jeo[i].x - jeo[j].x) * (jeo[i].x - jeo[j].x) + (jeo[i].y - jeo[j].y) * (jeo[i].y - jeo[j].y);
}
double CrossLeft(pint p1, pint p2, pint p3)//是否严格左转,共线不算左转
{
    return ((p3.x - p1.x) * (p2.y - p1.y) - (p2.x - p1.x) * (p3.y - p1.y));
}
bool online(pint p1, pint p2, pint p3)
{
    return (p3.x >= min(p1.x, p2.x) && p3.x <= max(p1.x, p2.x) && p3.y >= min(p1.y, p2.y) && p3.y <= max(p1.y, p2.y));
}
int main()
{
    int n;
    while(scanf("%d", &n) && n)
    {
        scanf("%lf%lf", &s.x, &s.y);
        double ans = 0;
        bool flag = true;
        for(int i = 0; i < n; i++)
        {
            scanf("%lf%lf", &jeo[i].x, &jeo[i].y);
            if (i != 0)
            {
                double tmp2 = CrossLeft(s, jeo[i - 1], jeo[i]);
                if (tmp2 >= -eps && tmp2 <= eps)
                {
                    if (online(jeo[i - 1], jeo[i], s)) flag = false;
                    continue;
                }
                double tmp = (dis(i) + dis(i - 1) - dis2(i, i - 1)) * 0.5 / (sqrt(dis(i) * dis(i - 1)));
                //cout << "sdfa " << tmp << endl;
                tmp = acos(tmp);
                //cout << "sdfa " << tmp << endl;
                if (tmp2 < -eps) ans += tmp;
                else if (tmp2 > eps) ans -= tmp;
                else if (online(jeo[i - 1], jeo[i], s)) flag = false;
            }
        }
        double tmp2 = CrossLeft(s, jeo[n - 1], jeo[0]);
        if (tmp2 >= -eps && tmp2 <= eps)
                {
                    if (online(jeo[n - 1], jeo[0], s)) flag = false;

                }
        else
        {
        double tmp = (dis(n - 1) + dis(0) - dis2(n - 1, 0)) * 0.5 / (sqrt(dis(n - 1) * dis(0)));
                tmp = acos(tmp);

                if (tmp2 < -eps) ans += tmp;
                else if (tmp2 > eps) ans -= tmp;
                else if (online(jeo[n - 1], jeo[0], s)) flag = false;
        }
        if (!flag) printf("Ouch!\n");
        else
        {
            //printf("%f\n", ans);
            ans /= 2 * 3.1415926;
            char x[10];
            //cout << ans << endl;
            sprintf(x, "%.0f", ans);
            int re;
            sscanf(x, "%d", &re);
            if (re > 0) printf("+%d\n", re);
            else printf("%d\n", re);
        }
    }
    return 0;
}

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有