HDU-2108- Shape of HDU(叉乘判断凸多边形)

tech2022-12-06  97

Shape of HDU

Problem Description

话说上回讲到海东集团推选老总的事情,最终的结果是XHD以微弱优势当选,从此以后,“徐队”的称呼逐渐被“徐总”所取代,海东集团(HDU)也算是名副其实了。 创业是需要地盘的,HDU向钱江肉丝高新技术开发区申请一块用地,很快得到了批复,据说这是因为他们公司研发的“海东牌”老鼠药科技含量很高,预期将占全球一半以上的市场。政府划拨的这块用地是一个多边形,为了描述它,我们用逆时针方向的顶点序列来表示,我们很想了解这块地的基本情况,现在请你编程判断HDU的用地是凸多边形还是凹多边形呢?

Input

输入包含多组测试数据,每组数据占2行,首先一行是一个整数n,表示多边形顶点的个数,然后一行是2×n个整数,表示逆时针顺序的n个顶点的坐标(xi,yi),n为0的时候结束输入。

Output

对于每个测试实例,如果地块的形状为凸多边形,请输出“convex”,否则输出”concave”,每个实例的输出占一行。

Sample Input

4 0 0 1 0 1 1 0 1 0

Sample Output

convex

解题思路:

叉乘判断凸多边形。 以下参考:https://www.cnblogs.com/wmxl/p/5294620.html

向量的叉乘如X叉乘Y就是一个垂直与X和Y组成的平面的一个向量,方向是这样决定的,右手四指与X的方向相同,大拇指与四指垂直,然后四指按照这样的方向绕,从X开始,经过X与Y的锐角的方向环绕,拇指所指的方向就是X叉乘Y的方向

叉乘是三维才有意义, 这里虽然是二维的, 但可以看成第三维z是0 所以计算结果就变成了(0, 0, x1y2 - x2y1)

叉乘的几何意义是 一个垂直于两个向量的方向, 如果所有边依次相乘的方向都是一样的, 就是凸多边形, 此题因为规定了必须逆时针, 所以所有相乘都必须是正的(这个可以自己试一下就知道)

AC代码:

#include <cstdio> #include <vector> #include <queue> #include <cstring> #include <cmath> #include <map> #include <set> #include <stack> #include <string> #include <iostream> #include <algorithm> #include <iomanip> using namespace std; #define sd(n) scanf("%d",&n) #define sdd(n,m) scanf("%d%d",&n,&m) #define sddd(n,m,k) scanf("%d%d%d",&n,&m,&k) #define pd(n) printf("%d\n", n) #define pc(n) printf("%c", n) #define pdd(n,m) printf("%d %d", n, m) #define pld(n) printf("%lld\n", n) #define pldd(n,m) printf("%lld %lld\n", n, m) #define sld(n) scanf("%lld",&n) #define sldd(n,m) scanf("%lld%lld",&n,&m) #define slddd(n,m,k) scanf("%lld%lld%lld",&n,&m,&k) #define sf(n) scanf("%lf",&n) #define sc(n) scanf("%c",&n) #define sff(n,m) scanf("%lf%lf",&n,&m) #define sfff(n,m,k) scanf("%lf%lf%lf",&n,&m,&k) #define ss(str) scanf("%s",str) #define rep(i,a,n) for(int i=a;i<=n;i++) #define per(i,a,n) for(int i=n;i>=a;i--) #define mem(a,n) memset(a, n, sizeof(a)) #define debug(x) cout << #x << ": " << x << endl #define pb push_back #define all(x) (x).begin(),(x).end() #define fi first #define se second #define mod(x) ((x)%MOD) #define gcd(a,b) __gcd(a,b) #define lowbit(x) (x&-x) #define pii map<int,int> #define mk make_pair #define rtl rt<<1 #define rtr rt<<1|1 #define Max(x,y) (x)>(y)?(x):(y) #define int long long typedef pair<int,int> PII; typedef long long ll; typedef unsigned long long ull; typedef long double ld; const int MOD = 1e9 + 7; const ll mod = 10007; const double eps = 1e-9; const ll INF = 0x3f3f3f3f3f3f3f3fll; //const int inf = 0x3f3f3f3f; inline int read(){int ret = 0, sgn = 1;char ch = getchar(); while(ch < '0' || ch > '9'){if(ch == '-')sgn = -1;ch = getchar();} while (ch >= '0' && ch <= '9'){ret = ret*10 + ch - '0';ch = getchar();} return ret*sgn;} inline void Out(int a){if(a>9) Out(a/10);putchar(a%10+'0');} int qpow(int m, int k, int mod){int res=1%mod,t=m%mod;while(k){if(k&1)res=res*t%mod;t=t*t%mod;k>>=1;}return res;} ll gcd(ll a,ll b){if(b > a) swap(a,b); return b==0?a : gcd(b,a%b);} ll lcm(ll a,ll b){return a/gcd(a,b)*b;} ll inv(ll x,ll mod){return qpow(x,mod-2,mod)%mod;} //const int N = 3e3+15; int t = 1,cas = 1; int n,m; const int N = 1e6+15; int primes[N], euler[N], pcnt; bool st[N]; void getEulers(int n) { //欧拉筛的扩展 euler[1] = 1; pcnt = 0; for (int i=2; i <= n; i++ ){ if ( !st[i] ){ primes[pcnt++] = i; euler[i] = i-1; } for ( int j=0; primes[j] <= n/i; j++ ){ st[ primes[j]*i ] = true; if ( i % primes[j] == 0 ) { euler[ i*primes[j] ] = euler[i] * primes[j]; break; } euler[ i*primes[j] ] = euler[i] * ( primes[j]-1 ); } } } int Euler(int n) { int m = (int)sqrt(n + 0.5); int ans = n; for (int i = 2; i <= m; ++i) { if (n % i == 0) { ans = ans / i *(i - 1); while (n % i == 0) n /= i; } } if (n > 1) ans = ans / n *(n - 1); return ans; } int a[N],b[N]; signed main() { while(cin>>n&&n) { for(int i = 0 ; i < n ; i ++) cin>>a[i]>>b[i]; b[n] = b[0];a[n] = a[0]; b[n+1] = b[1];a[n+1] = a[1]; int ans = 1; for(int i = 0 ; i < n ; i ++){ int x1 = a[i+2]-a[i+1]; int y1 = b[i+2]-b[i+1]; int x2 = a[i+1]-a[i]; int y2 = b[i+1]-b[i]; if(x1*y2-x2*y1 > 0){ ans = 0; } } if(ans) cout<<"convex"<<endl; else cout<<"concave"<<endl; } }
最新回复(0)