牛客练习赛18 B-简单多边形

B-简单多边形

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述

为了让所有选手都感到开心,Nowcoder练习赛总会包含一些非常基本的问题。 比如说:
按顺时针或逆时针方向给你一个简单的多边形的顶点坐标,请回答此多边形是顺时针还是逆时针。
输入描述:

输入包含N + 1行。
第一行包含一个整数N,表示简单多边形的顶点数。
在下面的N行中,第i行包含两个整数xi,yi,表示简单多边形中的第i个顶点的坐标。

输出描述:

如果简单多边形按顺时针顺序给出,则在一行中输出“clockwise”(不带引号)。 否则,打印”counterclockwise”(不带引号)。

示例1

输入

3
0 0
1 0
0 1

输出

counterclockwise

示例2

输入

3
0 0
0 1
1 0

输出

clockwise

问题分析

计算几何模板题。
如果是凸包,只需要判断前三个点即可,计算叉积,判断方向。但是这里还有可能是凹包,凹包的话首先,可以去凸包上的特殊点,x最大最小的点,y最大最小的点,这些极值点肯定是在凸包上的,可以计算这些的叉积,其次,直接统计叉积正负的数量,正多负少,是逆时针,反之,顺时针。
最简单的做法是直接计算面积,用面积的正负判断方向。

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

const int maxn = 200050;
const double eps = 1e-8;

struct Point{
    double x, y;
};
double cross(Point a,Point b,Point c) {
    return (a.x-c.x)*(b.y-c.y)-(b.x-c.x)*(a.y-c.y);
}
//计算多边形面积
double PolygonArea(Point p[], int n)
{
    if(n < 3) return 0.0;
    double s = p[0].y * (p[n - 1].x - p[1].x);
    p[n] = p[0];
    for(int i = 1; i < n; ++ i)
        s += p[i].y * (p[i - 1].x - p[i + 1].x);
    return s * 0.5;
}
Point p1[maxn];
int n1;
int main()
{
    while(scanf("%d",&n1) != EOF ){
        for(int i = 0; i < n1; i++)
            scanf("%lf%lf", &p1[i].x, &p1[i].y);
        if ( PolygonArea(p1,n1) > 0 )
            puts("counterclockwise");
        else
            puts("clockwise");
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Eternally831143/article/details/80448351