数学、半几何

来源:互联网 发布:linux中cd的使用 编辑:程序博客网 时间:2024/05/17 06:11

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

题目意思:

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

inputoutput

4 3 5
0 03 43 0
10 17 21
0 00 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 operatorusing 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 operatorusing 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;}


0 0