非精写版-51nod基础训练
Posted iuk11
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了非精写版-51nod基础训练相关的知识,希望对你有一定的参考价值。
四点共面
已知四个点,判断是否共面。可以求出三条向量,利用向量积求立方体体积,若体积是0,则四点共面。
求出的三个向量:
d
1
=
(
x
1
,
y
1
,
z
1
)
d_1=(x_1,y_1,z_1)
d1=(x1,y1,z1)
d
2
=
(
x
2
,
y
2
,
z
2
)
d_2=(x_2,y_2,z_2)
d2=(x2,y2,z2)
d
3
=
(
x
3
,
y
3
,
z
3
)
d_3=(x_3,y_3,z_3)
d3=(x3,y3,z3)
V
=
d
1
∗
d
2
∗
d
3
V=d_1*d_2*d_3
V=d1∗d2∗d3
V
=
(
x
1
y
2
z
3
+
x
2
y
3
z
1
+
x
3
y
1
z
2
)
−
(
x
1
y
3
z
2
+
x
2
y
1
z
3
+
x
3
y
2
z
1
)
V=(x_1y_2z_3+x_2y_3z_1+x_3y_1z_2)-(x_1y_3z_2+x_2y_1z_3+x_3y_2z_1)
V=(x1y2z3+x2y3z1+x3y1z2)−(x1y3z2+x2y1z3+x3y2z1)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
struct node{
int x,y,z;
}e[5],d[5];
int main(){
int t;
cin>>t;
while(t--){
for(int i=0;i<4;i++){
cin>>e[i].x>>e[i].y>>e[i].z;
if(i){
d[i].x=e[i-1].x-e[i].x;
d[i].y=e[i-1].y-e[i].y;
d[i].z=e[i-1].z-e[i].z;
}
}
ll d1=d[1].x*d[2].z*d[3].y+d[1].y*d[2].x*d[3].z+d[1].z*d[2].y*d[3].x;
ll d2=d[1].x*d[2].y*d[3].z+d[2].x*d[3].y*d[1].z+d[3].x*d[1].y*d[2].z;
if(d1==d2){
cout<<"Yes\\n";
}else{
cout<<"No\\n";
}
}
//system("pause");
return 0;
}
好像是因为贴代码的改版了,之前屯的发不了了。
线段相交
线段相交,是给出两两顶点,确定一条线段,判断两线段是否相交。
重点就在于判断线段是否相交,之前的数学思想是两直线是否相交,那么联立方程组,如果不平行,就一定相交。但线段的交点判断可不仅仅是对平行的判断。(之前的圆与三角形题目中也有求线段是否相交的要求)。
走迷宫
数据范围很小,只需要回溯记录每条路径即可。
#include<bits/stdc++.h>
using namespace std;
int dir[4][2]={
{1,0},{-1,0},{0,1},{0,-1}
};
int maps[10][10];
int vis[10][10];
int n,m,t;
int sx,sy;
int fx,fy;
int ans=0;
bool check(int x,int y){
if(x>n||y>m||x<1||y<1||maps[x][y]) return false;
return true;
}
void dfs(int x,int y){
if(x==fx&&y==fy){
ans++;
}
for(int i=0;i<4;i++){
int xx=x+dir[i][0];
int yy=y+dir[i][1];
if(!vis[xx][yy]&&check(xx,yy)){
vis[xx][yy]=1;
dfs(xx,yy);
vis[xx][yy]=0;
}
}
}
int main(){
cin>>n>>m>>t;
cin>>sx>>sy>>fx>>fy;
while(t--){
int x,y;
cin>>x>>y;
maps[x][y]=1;
}
vis[sx][sy]=1;
dfs(sx,sy);
cout<<ans<<endl;
//system("pause");
return 0;
}
迷宫游戏
之前(最短路径)那道题的dijkstra的板子。
用优先队列优化,优先队列用的好,dijkstra的时间复杂度就低。
在网上还找到了一份结构体的,但是结构体的重载很麻烦,不同的编译器可能会报错。用<pair>很方便。
思路就是我们只需要去寻找最短路就好,在路径传递的过程中把选中的点的权值加进去。如果有多条最短路,即有两个点间的两条路径的边权相同,就去比较一下谁的点权大,谁大就加谁的点权。最后维护出来到终点的mon[]数组,记录的就是最短路径下的最大点权。
#include<bits/stdc++.h>
using namespace std;
const int maxn=505;
const int INF=0x3f3f3f3f;
int n,m,s,t;
int d[maxn];
int val[maxn];
int mon[maxn];
vector<pair<int,int> >E[maxn];
void init(){
for(int i=0;i<maxn;i++) d[i]=INF;
for(int i=0;i<maxn;i++) E[i].clear();
}
void dijkstra(int x){
d[x]=0;
mon[x]=val[x];
priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > >Q;
Q.push(make_pair(d[x],x)); //优先队列自动根据pair中的first从大到小排序(默认), 放入 负距离,则 边短的先弹出
while(!Q.empty()){
int now=Q.top().second; //显然,now 为一个起点
Q.pop();
if(now==t) break;
for(int j=0;j<E[now].size();j++){
int v=E[now][j].first; //显然,v 为 now 可以到达的一个终点
if(d[v]>d[now]+E[now][j].second){ //如果 已知的v 到 s 的距离 大于 now这个点到 s 的距离 + now 这个点到 v 的距离, 更新一下, 并放入优先队列
d[v]=d[now]+E[now][j].second;
mon[v]=val[v]+mon[now];
Q.push(make_pair(d[v],v));
}else if(d[v]==d[now]+E[now][j].second){
if(mon[v]<val[v]+mon[now]){
mon[v]=val[v]+mon[now];
Q.push(make_pair(v,d[v]));
}
}
}
}
return;
}
int main(){
cin>>n>>m>>s>>t;
s++;t++;
init();
for(int i=1;i<=n;i++) cin>>val[i];
int u,v,w;
for非精写版-51nod基础训练