poj(2318)——TOYS(叉积的简单应用)

部署运行你感兴趣的模型镜像

第一道计算几何题。。

题意:

在一个长方形盒子中被线段划分成了几段区域,然后每段区域中都有一些物品,让你判断在每个区域中分别有几个物品。

叉积的简单应用:

这就要用到向量叉积。叉积的一个非常重要的性质是通过它的符号判断两向量相互之间的顺逆时针关系:设向量P=(x1,y1),Q=(x2,y2)

如果P*Q>0则P在Q的顺时针方向;

如果P*Q=0则P与Q共线,可能同向,与可能反向;

如果P*Q<0则P在Q的逆时针方向。

  (请注意这里是叉乘)


这里要注意一点就是我们在做叉积的时候,要先选择好是按照下面还是按照上面部分作为起始点。也就是在算向量时的起始点。要不然的话会使叉积的顺时针或是逆时针不同,这样就会使答案不一样了。


#include<cstdio>
#include<cstring>
#include<map>
#include<set>
#include<cmath>
#include<algorithm>
#include<vector>
#include<queue>
#include<iostream>
#include<time.h>
using namespace std;
typedef __int64 ll;
typedef unsigned __int64 ULL;
#define pi acos(-1.0)
#define Ex exp(1.0)
#define maxn 5050*2
int vis[5050];
struct node{
    int x,y,idx;
}a[maxn],b[maxn];
struct Point{
    int x,y;
    Point(int x=0,int y=0):x(x),y(y){}
};
typedef Point Vector;
Vector operator - (Point A,Point B){
    return Vector(A.x-B.x,A.y-B.y);
}
Vector operator * (Point A,double p){
    return Vector(A.x*p,A.y*p);
}
int Cross(Vector A,Vector B){
    return A.x*B.y-A.y*B.x;
}
int main(){
    int n,m,x1,y1,x2,y2;
    while(~scanf("%d",&n)){
        if(n==0) break;
        memset(a,0,sizeof(a));
        memset(b,0,sizeof(b));
        scanf("%d%d%d%d%d",&m,&x1,&y1,&x2,&y2);
        for(int i=1;i<=n;i++){
            int u,v;
            scanf("%d%d",&u,&v);
            a[i].x=u,a[i].y=y1,a[i+5000].x=v,a[i+5000].y=y2;
            //我这里是选择了y1作为下面,也就是向量的起始点,要不然会导致错误
            //因为如果不统一的话会导致一会儿以上面的点算为起始点,一会儿以下面的点作为起始点
            //从而导致叉积的不同,从而导致无法统一方向。
            swap(a[i].x,a[i+5000].x);
            swap(a[i].y,a[i+5000].y);
        }
        for(int i=1;i<=m;i++){
            int u,v;
            scanf("%d%d",&u,&v);
            b[i].x=u,b[i].y=v;
        }
        memset(vis,0,sizeof(vis));
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                if(vis[j]) continue;
                Vector A,B,C;
                A.x=a[i].x;
                A.y=a[i].y;
                B.x=a[i+5000].x;
                B.y=a[i+5000].y;
                C.x=b[j].x;
                C.y=b[j].y;
                C=C-A;
                A=B-A;
                if(Cross(C,A)>0){
                    if(i==n){
                        vis[j]=1;
                        a[i].idx++;
                        continue;
                    }
                    Vector D,E,F;
                    D.x=a[i+1].x;
                    D.y=a[i+1].y;
                    E.x=a[(i+1)+5000].x;
                    E.y=a[(i+1)+5000].y;
                    F.x=b[j].x;
                    F.y=b[j].y;
                    F=F-D;
                    D=E-D;
                    if(Cross(F,D)<0){
                        vis[j]=1;
                        a[i].idx++;
                    }
                }
                else if(Cross(C,A)<=0){
                    if(i==1){
                        vis[j]=1;
                        a[i-1].idx++;
                        continue;
                    }
                    Vector D,E,F;
                    D.x=a[i-1].x;
                    D.y=a[i-1].y;
                    E.x=a[(i-1)+5000].x;
                    E.x=a[(i-1)+5000].y;
                    F.x=b[j].x;
                    F.y=b[j].y;
                    F=F-D;
                    D=E-D;
                    if(Cross(F,D)>0){
                        vis[j]=1;
                        a[i-1].idx++;
                    }
                }
            }
        }
        for(int i=0;i<=n;i++){
            printf("%d: %d\n",i,a[i].idx);
        }
        printf("\n");
    }
    #ifndef ONLINE_JUDGE
    system("pause");
    #endif
    return 0;
}
/*
5 6 0 10 60 0
3 1
4 3
6 8
10 10
15 30
1 5
2 1
2 8
5 5
40 10
7 9
*/


您可能感兴趣的与本文相关的镜像

Stable-Diffusion-3.5

Stable-Diffusion-3.5

图片生成
Stable-Diffusion

Stable Diffusion 3.5 (SD 3.5) 是由 Stability AI 推出的新一代文本到图像生成模型,相比 3.0 版本,它提升了图像质量、运行速度和硬件效率

### Unity 中 (`Vector3.Cross`) 的计算方法与应用场景 在 Unity 中,`Vector3.Cross` 方法用于计算两个向量的(Cross Product)。该操作的结果是一个新向量,这个向量垂直于输入的两个向量所构成的平面[^1]。具体来说,假设存在两个三维向量 \( \vec{A} = (a_x, a_y, a_z) \) 和 \( \vec{B} = (b_x, b_y, b_z) \),则它们的可以按照如下公式计算得出: \[ \vec{C} = \vec{A} \times \vec{B} = \begin{vmatrix} i & j & k \\ a_x & a_y & a_z \\ b_x & b_y & b_z \end{vmatrix} = ((a_y b_z - a_z b_y), -(a_x b_z - a_z b_x), (a_x b_y - a_y b_x)) \] 其中 \( i, j, k \) 分别代表沿 x 轴、y 轴和 z 轴方向上的单位向量。 下面通过一段代码示例说明如何利用 `Vector3.Cross` 来获得两个向量间的法线向量: ```csharp using UnityEngine; public class CrossProductExample : MonoBehaviour { void Start() { // 定义两个向量 A 和 B Vector3 vecA = new Vector3(1, 0, 0); Vector3 vecB = new Vector3(0, 1, 0); // 计算这两个向量的 Vector3 crossResult = Vector3.Cross(vecA, vecB); // 打印结果到控制台 Debug.Log("The result of the cross product is: " + crossResult.ToString()); /* 结果应该是 (0, 0, 1),因为: | i j k | | 1 0 0 | = (0*0 - 0*1)i - (1*0 - 0*0)j + (1*1 - 0*0)k = (0,-0,+1) | 0 1 0 | */ } } ``` #### 应用场景分析 - **表面朝向检测**:当你拥有三角形或者四边形网格模型时,可以通过对其边上两点组成的向量做得到面片法线,从而判定光照强度或碰撞反应等。 - **旋转轴构建**:如果已知物体移动前后的位移差作为第一个向量,再取任意固定参照物至目标中心连线作第二个向量,则可借助找出绕哪个轴转动最为合适[^2]。 - **力矩模拟**:物理学中常用到杠杆原理,即施加外力产生的扭矩等于力臂长度乘以作用力大小投影值。此时便可以用到来快速求解力矩矢量的方向及其模长。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值