FZU

来源:互联网 发布:lol物品数据库 编辑:程序博客网 时间:2024/05/16 05:57

题目网址点击打开链接



读题有问题:convex quadrilateral凸边形,一开始,,看成了多边形,我说怎么这么多人出了题,

                   还有一句话没看见:Two convex quadrilaterals are considered different if they lie in the different position in the sky.

                  回去好好学英语吧


一种方法,判断是否为凸四边形,用叉积判断;

叉乘结果是|a||b|sinQ;所以可以根据征服来判断该角是否大于180,只要有一个角大,那他必然是凸

但是注意:叉乘方向,a*b  和b*a表示的角 是不一样的(高数学的都忘了。。。)

还要注意点的顺序,逆时针顺时针是不一样的

#include <iostream>#include <cstdio>#include <cstring>#include <cctype>#include <list>#include <algorithm>#include<queue>#include<vector>#include<set>#include<cmath>using namespace std;int n;int x[35];int y[35];int qu(int a,int b,int c){    return (x[b]-x[a])*(y[c]-y[a])-(y[b]-y[a])*(x[c]-x[a]);}int build(int a,int b,int c,int d){//   cout<<qu(a,b,d)<<" ";//   cout<<qu(b,c,a)<<" ";//   cout<<qu(c,d,b)<<" ";//   cout<<qu(d,a,c)<<" "<<endl;;    if(qu(a,b,d)<=0)      return 0;    if(qu(b,c,a)<=0)     return 0;    if(qu(c,d,b)<=0)     return 0;    if(qu(d,a,c)<=0)     return 0;    return 1;}int main(){    int T;    cin>>T;    for(int k=1;k<=T;k++)    {        cin>>n;        for(int i=0;i<n;i++)        {            cin>>x[i]>>y[i];        }        //s.clear();        int num=0;        for(int i=0;i<n;i++)            for(int j=i+1;j<n;j++)              for(int a=j+1;a<n;a++)                for(int b=a+1;b<n;b++)               {                   //cout<<"No   d"<<endl;                  if(build(i,a,b,j)) { num++; continue;}                  if(build(i,j,b,a)) { num++; continue;}                  if(build(i,b,a,j)) { num++; continue;}                  if(build(i,j,a,b)) { num++; continue;}                  if(build(i,a,j,b)) { num++; continue;}                  if(build(i,b,j,a)) { num++; continue;}               }         printf("Case %d: ",k);         cout<<num<<endl;    }    return 0;}

还有一种方法 ,就是判断是否为凹四边形,对于任意一个凹四边形,画图判断会发现,只要出现 一个点在另外三个点形成的三角形内部即为凹,开始我的方法比较麻烦所以放弃了这种做法,但是网上是这样做的,,Sabc=Sabd+Sadc+Sbdc的话,d就是那个点,所以判断每一个点:

#include <stdio.h>#include <string.h>#include <math.h>const int N = 50;struct point {int x, y;void get() { scanf("%d%d", &x, &y); }}p[N];int n;void init() {scanf("%d", &n);for (int i = 0; i < n; i++) { p[i].get(); }}double area(point a, point b, point c) {return a.x * b.y + c.x * a.y + b.x * c.y - c.x * b.y - a.x * c.y - b.x * a.y;}bool OK(point a, point b, point c, point d) {double sum = fabs(area(a, b, d)) + fabs(area(a, c, d)) + fabs(area(b, c, d));double tmp = fabs(area(a, b, c));if (fabs(sum - tmp) < 1e-9) return true;return false;}bool judge(point a, point b, point c, point d) {if (OK(a, b, c, d)) return false;if (OK(a, b, d, c)) return false;if (OK(a, c, d, b)) return false;if (OK(b, c, d, a)) return false;return true;}int solve() {int ans = 0;for (int i = 0; i < n; i++) {for (int j = i + 1; j < n; j++) {for (int x = j + 1; x < n; x++) {for (int y = x + 1; y < n; y++) {if (judge(p[i], p[j], p[x], p[y])) ans++;}}}}return ans;}int main () {int cas;scanf("%d", &cas);for (int i = 1; i <= cas; i++) {init();printf("Case %d: %d\n", i, solve());}return 0;}