数学、半几何

2024-08-31 12:58
文章标签 数学 几何

本文主要是介绍数学、半几何,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

http://acm.hust.edu.cn/vjudge/contest/view.action?cid=64147#problem/I

题目意思:

输入三角形的三条边长,均为整数,范围 |  |<=1e7。问是否存在整数点坐标满足这个三角形。如果存在,输出任意一组解。

input output
4 3 5
0 0
3 4
3 0
10 17 21
0 0
0 21
-8 15
100 100 100
-1

分析:刚开始用几何思想去做,先找出一组解,尽管不是整数点,但是rotate旋转,看是否有解,我还用了3条边的全排列顺序。结果不是wa就是TLE。==

中午相当测试下半径1e7的圆有多少整数点,发现100不到,<<100个,如此就想暴力了。把圆上的点都预处理出来,在暴力2个圆上的点,判断另一条边的长度是否有解。一发A了。

AC代码:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
#include<stack>
#define rt return
#define bk break
#define ct continue
#define sf scanf
#define pf printf
#define ms memset
#define si(n) sf("%d",&n)
#define pi(n) pf("%d\n",n)
#define REP0(i,n) for(int i=0;i<(n);i++)
#define REP1(i,n) for(int i=1;i<=(n);i++)
#define REP(i,s,n) for(int i=s;i<=(n);i++)
#define db double
#define pb push_back
#define LL long long
#define INF 0x3fffffff
#define eps 1e-8
#define PI acos(-1)
#define maxn 1001
#define op operator
using namespace std;
struct node{db x,y;node(db a=0,db b=0){x=a,y=b; }node op - (node a){rt node(x-a.x,y-a.y); }db dis(){rt sqrt(x*x+y*y); }void out(){pf("%d %d\n",(int)x,(int)y); }
};
int sig(db x){rt (x>eps)-(x<-eps); }
int solve(node p[],int R){//将半径为R的圆上的整数点保存在p数组中,返回个数db r=R*1.0;int cnt=0;p[cnt].x=0,p[cnt].y=r;cnt++;p[cnt].x=0,p[cnt].y=-r;cnt++;p[cnt].x=r,p[cnt].y=0;cnt++;p[cnt].x=-r,p[cnt].y=0;cnt++;for(int x=1;x<r;x++){//第一象限db y=sqrt(r*r-1.0*x*x);if(sig(y-(int)y)==0){p[cnt].x=x,p[cnt].y=y;cnt++;p[cnt].x=x,p[cnt].y=-y;cnt++;p[cnt].x=-x,p[cnt].y=y;cnt++;p[cnt].x=-x,p[cnt].y=-y;cnt++;}}rt cnt;
}
bool judge(node p[],int cnt1,node q[],int cnt2,db r){for(int i=0;i<cnt1;i++){for(int j=0;j<cnt2;j++){if(sig((p[i]-q[j]).dis()-r)==0){pf("0 0\n");p[i].out();q[j].out();rt true;}}}rt false;
}
int main(){db a,b,c;while(~sf("%lf%lf%lf",&a,&b,&c)){node PA[1001],PB[1001],PC[1001];int cntA=solve(PA,a);int cntB=solve(PB,b);int cntC=solve(PC,c);if(judge(PA,cntA,PB,cntB,c)==false)if(judge(PA,cntA,PC,cntC,b)==false)if(judge(PB,cntB,PC,cntC,a)==false)puts("-1");}rt 0;
}
//如果求圆内以及圆上的个数,一样可以求个数,但是点数很多。

WA、TLE代码:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
#include<stack>
#define rt return
#define bk break
#define ct continue
#define sf scanf
#define pf printf
#define ms memset
#define si(n) sf("%d",&n)
#define pi(n) pf("%d\n",n)
#define REP0(i,n) for(int i=0;i<(n);i++)
#define REP1(i,n) for(int i=1;i<=(n);i++)
#define REP(i,s,n) for(int i=s;i<=(n);i++)
#define db double
#define pb push_back
#define LL long long
#define INF 0x3fffffff
#define eps 1e-10
#define PI acos(-1)
#define maxn
#define op operator
using namespace std;
int sig(db x){rt (x>eps)-(x<-eps); }
struct node{db x,y;node(){}node(db a,db b){x=a,y=b;}node op - (node a){rt node(x-a.x,y-a.y); }db op * (node a){rt x*a.x+y*a.y; }db op ^ (node a){rt x*a.y-a.x*y; }db dis(){rt sqrt(x*x+y*y); }node rota(db d){node a;a.x=x*cos(d)-y*sin(d);a.y=y*cos(d)+x*sin(d);rt a;}void out(){pf("%d %d\n",(int)x,(int)y);}
};
bool check(node B){if(sig(B.x-(int)B.x)==0&&sig(B.y-(int)B.y)==0)rt true;rt false;
}
bool solve(db a,db b,db c){node A(0,0);node C(b,0);node tmp(c,0);db d=acos((b*b+c*c-a*a)/(2.0*b*c));node B=tmp.rota(d);db r=b;for(int x=r;x>=1;x--){db y=sqrt(r*r-x*x);if(sig(y-(int)y)!=0)continue;db ang=atan(y/x);node B1=B.rota(ang);node C1=C.rota(ang);if(check(B1)&&check(C1)){A.out();B1.out();C1.out();rt true;}}rt false;
}
int main(){double num[3];while(~sf("%lf%lf%lf",&num[0],&num[1],&num[2])){sort(num,num+3);bool ok=false;do{db a=num[0],b=num[1],c=num[2];if(solve(a,b,c)){ok=true;break;}}while(next_permutation(num,num+3));if(ok==false)pf("-1\n");}rt 0;
}


这篇关于数学、半几何的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1123975

相关文章

uva 10387 Billiard(简单几何)

题意是一个球从矩形的中点出发,告诉你小球与矩形两条边的碰撞次数与小球回到原点的时间,求小球出发时的角度和小球的速度。 简单的几何问题,小球每与竖边碰撞一次,向右扩展一个相同的矩形;每与横边碰撞一次,向上扩展一个相同的矩形。 可以发现,扩展矩形的路径和在当前矩形中的每一段路径相同,当小球回到出发点时,一条直线的路径刚好经过最后一个扩展矩形的中心点。 最后扩展的路径和横边竖边恰好组成一个直

uva 10014 Simple calculations(数学推导)

直接按照题意来推导最后的结果就行了。 开始的时候只做到了第一个推导,第二次没有继续下去。 代码: #include<stdio.h>int main(){int T, n, i;double a, aa, sum, temp, ans;scanf("%d", &T);while(T--){scanf("%d", &n);scanf("%lf", &first);scanf

uva 10025 The ? 1 ? 2 ? ... ? n = k problem(数学)

题意是    ?  1  ?  2  ?  ...  ?  n = k 式子中给k,? 处可以填 + 也可以填 - ,问最小满足条件的n。 e.g k = 12  - 1 + 2 + 3 + 4 + 5 + 6 - 7 = 12 with n = 7。 先给证明,令 S(n) = 1 + 2 + 3 + 4 + 5 + .... + n 暴搜n,搜出当 S(n) >=

uva 11044 Searching for Nessy(小学数学)

题意是给出一个n*m的格子,求出里面有多少个不重合的九宫格。 (rows / 3) * (columns / 3) K.o 代码: #include <stdio.h>int main(){int ncase;scanf("%d", &ncase);while (ncase--){int rows, columns;scanf("%d%d", &rows, &col

【生成模型系列(初级)】嵌入(Embedding)方程——自然语言处理的数学灵魂【通俗理解】

【通俗理解】嵌入(Embedding)方程——自然语言处理的数学灵魂 关键词提炼 #嵌入方程 #自然语言处理 #词向量 #机器学习 #神经网络 #向量空间模型 #Siri #Google翻译 #AlexNet 第一节:嵌入方程的类比与核心概念【尽可能通俗】 嵌入方程可以被看作是自然语言处理中的“翻译机”,它将文本中的单词或短语转换成计算机能够理解的数学形式,即向量。 正如翻译机将一种语言

poj 1113 凸包+简单几何计算

题意: 给N个平面上的点,现在要在离点外L米处建城墙,使得城墙把所有点都包含进去且城墙的长度最短。 解析: 韬哥出的某次训练赛上A出的第一道计算几何,算是大水题吧。 用convexhull算法把凸包求出来,然后加加减减就A了。 计算见下图: 好久没玩画图了啊好开心。 代码: #include <iostream>#include <cstdio>#inclu

uva 1342 欧拉定理(计算几何模板)

题意: 给几个点,把这几个点用直线连起来,求这些直线把平面分成了几个。 解析: 欧拉定理: 顶点数 + 面数 - 边数= 2。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#inc

XTU 1237 计算几何

题面: Magic Triangle Problem Description: Huangriq is a respectful acmer in ACM team of XTU because he brought the best place in regional contest in history of XTU. Huangriq works in a big compa

poj 3304 几何

题目大意:给出n条线段两个端点的坐标,问所有线段投影到一条直线上,如果这些所有投影至少相交于一点就输出Yes!,否则输出No!。 解题思路:如果存在这样的直线,过投影相交点(或投影相交区域中的点)作直线的垂线,该垂线(也是直线)必定与每条线段相交,问题转化为问是否存在一条直线和所有线段相交。 若存在一条直线与所有线段相交,此时该直线必定经过这些线段的某两个端点,所以枚举任意两个端点即可。

POJ 2318 几何 POJ 2398

给出0 , 1 , 2 ... n 个盒子, 和m个点, 统计每个盒子里面的点的个数。 const double eps = 1e-10 ;double add(double x , double y){if(fabs(x+y) < eps*(fabs(x) + fabs(y))) return 0 ;return x + y ;}struct Point{double x , y