20160407】讲了些杂题,思考了考向量,顺便抒下情x

本文探讨了向量在解决复杂折线问题中的应用,包括如何利用向量的叉乘来判断线段位置关系,并给出一道具体题目——蛇能否通过小洞的判断算法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

不知不觉养成了写博客的习惯啊……

今天讲了很多脑洞题,顺便老司机发车失败x

讲了很多智商题,感觉自己的智商又一次得到了升华,顺便感觉莫比乌斯反演简直没有学好QuQ【数学这么菜,不敢自称磨子桥技校的人了】然后上次ACM的题也讲了讲【终于看懂题意了好开心x】【前排膜拜红衣少shen年benYJQ,黑衣少shen年benTPZ,黑框少shen年benXGG

于是在机房颓lushiOJ的一大群人【假装自己不在内】下午刷了很多题,然而蒟蒻Flaze拼了老命终于码完了昨天的某题,发现WA得飞起是因为<=打成了<好嘛……学习神犇数组从零号节点开始用然而浪着浪着就改成了从一开始……于是浪得WA成了JQ红x


嗯关于向量,我表示想引用数学必修5的一句话“你感受到向量的威力了吗”,具体在哪里我也忘了

Flaze以前并没有做过直线相关(或者说是坐标相关)的题,今天表示被吓傻了

·存直线/线段的话就可以直接存一个端点+向量表示线

·对于向量a(x1,y1)和向量b(x2,y2)【后面的a和b都假装是向量吧】,a·b=x1*x2+y1*y2; a×b=x1*y2-x2*y1;大概是模乘cosα和模乘sinα什么的……反正已经记混了到时候要用的话推一下就好x

·叉乘似乎的出来的是一个方向奇怪的向量(平行四边形面积?),据红衣【重音】少年科普,方向什么的参考右手定则,总之逆时针的话朝纸外,顺时针朝纸里【用心感受就好x】

·叉乘不满足交换率,但是a×b= -b×a

·于是用叉乘来判断两个点(坐标)向量的位置就很有趣了,a*b如果是正的话,b在a的逆时针方向,反之亦然(懒似我)【记得数学课似乎讲过逆时针的角是正的,然而向量之间的角∈[0,π]

·判断一条直线和一条线段是否相交可以直接用两个端点叉乘直线的向量表示,然后把结果乘起来,如果小于零就相交【下面程序里的ovr()函数就是这个

·然后……呃……求两条直线的交点的话用这个奇怪的式子↓【直接背反正推的话也记不住怎么推x

假装两条直线a和b是这样的:

每条直线都是两个向量P和v,P是直线上某个点,v是方向啥的

则a和b的交点是

a.P+((b.v×(a.P-b.P))/(a.v×b.v))*a.v

反正向量和坐标啥的差不多x



下午其实就写了一道脑洞题,题面如下

B
问题描述:
蛇是由 n 个点构成的折线(没有自交)。 初始时, 蛇的第 i 个点在坐标(xi,yi)处, 蛇可以通过旋
转或者平移连续移动,但是它不能改变自己的形状。 y=0 这条直线是一堵墙,在坐标(0,0)
处有一个小洞。问这个蛇能否从这个洞里通过(刚开始蛇身y坐标大于0,移动后蛇身y
标均小于 0)
输入:
第一行包含一个 T,表示测试组数(T<=5)
每组测试数据首先输入一个 n,表示蛇节点数。
接下来 n 行,第 i 行两个数 xi,yi 表示初始蛇第 i 节点坐标
输入保证蛇不会自交并且没有重点,三点不共线。。
输出:
输出 T 行,如果蛇可以通过,输出 Yes,否则 No
样例输入:
2

4

1
1 1
1 2
2 2
11
63 106
87 143
102 132
115 169
74 145
41 177
56 130
28 141
19 124
0 156
22 183
样例输出:
Yes
No
数据范围:
对于 50%的数据, 1<=n<=10
对于 100%的数据, 1<=n<=1000
T<=5,0<=xi<=1000000000,1<=yi<=1000000000


【粘上来格式好丑……】

不要脸的Flaze表示四处膜拜神犇终于搞懂了向量的叉乘和凸包的某些东西……于是胡搞乱搞从某想偷懒的神犇lpx处get的算法欢快地WA飞,思考了考看着数据顺便看了std,然后觉得自己的智商得到了升华

假装自己看懂了题解于是整理整理扔在下面,如果有bug的话,啊哈哈哈哈我什么都不知道

1)对于每个点(此处和后文都指转折点)来说,每条不和它相连的线段(如果是以它为节点的线段的话也并没有什么影响),相当于覆盖了一段角度

2)对于每个点把整条折线切成的两段折线,只有两段折线对于当前节点都各覆盖了不到180°,才可以使整条蛇钻出去

3)脑跑一下,如果是两边都不到180°,但两边的角度有重合的话,一定会有其他的点出现超过180°的情况

4)其他的就看程序意会吧


【Flaze的程序里写了太多用不上的向量操作,其实只用记录每个节点的位置就好,线段其实并不重要23333

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<iostream>
using namespace std;	int T,n;

struct t1{
	double x,y;
	t1(){}
	t1(double x1,double x2){
		x=x1,y=x2;
	}
};
t1 operator-(t1 a,t1 b){
	return t1(a.x-b.x,a.y-b.y);
}
t1 operator*(double a,t1 b){
	return t1(b.x*a,b.y*a);
}
double operator*(t1 a,t1 b){
	return a.x*b.x+a.y*b.y;
}
t1 operator+(t1 a,t1 b){
	return t1(a.x+b.x,a.y+b.y);
}
double det(t1 a,t1 b){
	return a.x*b.y-a.y*b.x;
}
struct vec{
	t1 S,P;
	bool tag;
}edge[1057];
bool tag_node[1057];

bool ovr(t1 S,t1 T,t1 v){
	return det(S,v)*det(T,v)<0;
}

bool check(int now,int L,int R){
	int lb=L;
	for(int i=L;i<=R;++i)	if(det(edge[lb].S-edge[now].S,edge[lb].S-edge[i].S)>0)	lb=i;
	for(int i=L;i<=R;++i)	if(det(edge[lb].S-edge[now].S,edge[lb].S-edge[i].S)>0)	return 0;
	return 1;
}

int main(){
	freopen("1.in","r",stdin);
	scanf("%d",&T);
	while(T--){
		int flg=1;
		memset(edge,0,sizeof(edge));
		memset(tag_node,0,sizeof(tag_node));
		scanf("%d",&n);
		scanf("%lf%lf",&edge[1].S.x,&edge[1].S.y);
//		cout<<edge[1].S.x<<' '<<edge[1].S.y<<endl;
		for(int i=2;i<=n;++i){
			scanf("%lf%lf",&edge[i].S.x,&edge[i].S.y);
			edge[i-1].P=edge[i].S-edge[i-1].S;
//			cout<<edge[i].S.x<<' '<<edge[i].S.y<<endl;			
		}
		for(int i=1;i<=n;++i)	
			if((!check(i,1,i-1))||(!check(i,i+1,n))){
				flg=0;
				break;
			}
		if(!flg)
			printf("No\n");
		else	printf("Yes\n");
	}
	return 0;
}


随手发车:1slf2R3f【大雾

说起来离SCTSC还有一天多?lk学姐加油_(:зゝ∠)_

于是写得差不多了?那我去1702颓狼人游戏了【然而似乎张教主在隔壁????忽然有了危机感x


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值