FZU - 2148 I - Moon Game (暴力 叉积判凸多边形)

题目网址点击打开链接



读题有问题: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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值