URAL 2032 - Conspiracy Theory and Rebranding【本源勾股数组】

【题意】

给出三角形的三个边长,均是10^7以内的整数,问三角形的三个角的坐标是否能均是整数,输出其中任意一个解。

【题解】

一开始想的是枚举一条边的横坐标,然后通过勾股定理以及算角度求出其他点的坐标,再判断是否符合条件。

亲测TLE

直到知道了本源勾股数组的构造方法。。。

每个本源勾股数组(a,b,c)满足a*a+b*b=c*c,其中a为奇数,b为偶数。。

枚举s,t(1<=t<s,且它们是没有公因数的奇数)

a=st  b=(s*s-t*t)/2  c=(s*s+t*t)/2

因为最大数c=(s*s+t*t)/2  所以最多枚举到sqrt(2*c)即可。

假设三角形的三个点分别为p,q和r

我们先固定一个点为p(0,0),另外一个点q与它的距离是x,还有一个点r与它的距离是y。那么q的距离与r的距离一定是z

我们枚举勾股数组,如果勾股数组(a1,b1,c1)的c1,也就是最大的那个数,等于x,那么x的坐标为(a1,b1)【当然也可以是(a1,-b1),(-a1,b1),(-a1,-b1),均需要枚举,下同】

然后枚举c等于y的勾股数组,(a2,b2,c2),那么r点坐标为(a2,b2) 【可以事先把这些坐标预处理出来,放入vector中】

接下来判断两坐标是否相距为z即可。

注意通过这种方法求出来的勾股数组的a是奇数,也就是说它们的倍数 (i*a,i*b,i*c),i是一个正整数,并不会被求出来,我们要求的是i*c==x,那么只要满足x mod c=0我们就可以把勾股数组乘以x/c,加入备选选项中。

注意(0,x) (0,-x) (x,0) (-x,0)以及(0,y) (0,-y) (y,0) (-y,0) 不会在枚举本源勾股数组中出现,所以需要自己手动判断。

#include<bits/stdc++.h>
#define eps 1e-9
#define FOR(i,j,k) for(int i=j;i<=k;i++)
#define MAXN 1005
#define MAXM 40005
#define INF 0x3fffffff
#define PB push_back
#define MP make_pair
#define X first
#define Y second
#define lc (k<<1)
#define rc ((k<<1)1)
using namespace std;
typedef long long LL;
LL i,j,k,n,m,x,y,T,ans,big,cas,num,len;
bool flag;
LL z;
LL mx,sum,a,b,c;
vector <pair<LL,LL> > xx,yy;

LL gcd(LL x, LL y)
{
    return y ? gcd(y, x % y) : x;
}

int main()
{
    scanf("%I64d%I64d%I64d",&x,&y,&z);
    if (x>y) swap(x,y);
    if (y>z) swap(y,z);
    if (x>y) swap(x,y);
    mx=(LL)(sqrt(2*z)+eps);

    for (i=1;i<=mx;i+=2)//枚举本源勾股数组
    {
        for (j=i+2;j<=mx;j+=2)
        {
            if (gcd(i,j)>1) continue;
            a=i*j;
            b=(j*j-i*i)/2;
            c=(j*j+i*i)/2;
            if (x%c==0)
            {
                xx.PB(MP(a*x/c,b*x/c));
                xx.PB(MP(a*x/c,-b*x/c));
                xx.PB(MP(-a*x/c,b*x/c));
                xx.PB(MP(-a*x/c,-b*x/c));
                xx.PB(MP(b*x/c,a*x/c));
                xx.PB(MP(b*x/c,-a*x/c));
                xx.PB(MP(-b*x/c,a*x/c));
                xx.PB(MP(-b*x/c,-a*x/c));
            }
            if (y%c==0)
            {
                yy.PB(MP(a*y/c,b*y/c));
                yy.PB(MP(a*y/c,-b*y/c));
                yy.PB(MP(-a*y/c,b*y/c));
                yy.PB(MP(-a*y/c,-b*y/c));
                yy.PB(MP(b*y/c,a*y/c));
                yy.PB(MP(b*y/c,-a*y/c));
                yy.PB(MP(-b*y/c,a*y/c));
                yy.PB(MP(-b*y/c,-a*y/c));
            }
        }
    }
    xx.PB(MP(0,x));xx.PB(MP(x,0));xx.PB(MP(0,-x));xx.PB(MP(-x,0));
    yy.PB(MP(0,y));yy.PB(MP(y,0));yy.PB(MP(0,-y));yy.PB(MP(-y,0));

    for (i=0;i<xx.size();i++)
    {
        for (j=0;j<yy.size();j++)
        {
            if ((xx[i].X-yy[j].X)*(xx[i].X-yy[j].X)+(xx[i].Y-yy[j].Y)*(xx[i].Y-yy[j].Y)==z*z)
            {
                printf("0 0\n%I64d %I64d\n%I64d %I64d\n",xx[i].X,xx[i].Y,yy[j].X,yy[j].Y);
                return 0;
            }
        }
    }
    printf("-1\n");
    return 0;
}
时间: 2024-10-26 15:48:06

URAL 2032 - Conspiracy Theory and Rebranding【本源勾股数组】的相关文章

ural 2032 Conspiracy Theory and Rebranding (数学水题)

ural 2032  Conspiracy Theory and Rebranding 链接:http://acm.timus.ru/problem.aspx?space=1&num=2032 题意:给定一个三角形的三条边 (a, b, c),问是否可放在二维坐标,使得3个顶点都是整数点.若可以,输出任意一组解,否则,输出 -1. 思路:暴力枚举:以 a 为半径做第一象限的 1/4 圆, 以 b 为半径做 一.四 象限的半圆,存储整数点的解,暴力枚举 a 整数点与 b 整数点是否构成长度为 c

勾股数组及其应用uva106

勾股数组 设三元组(a,b,c)满足a^2 + b^2 = c^2的勾股数组,那么是否存在无穷多个勾股数组呢, 答案是肯定的,将三元组乘以d,可以得到新的三元组(da,db,dc) 即(da)^2 + (db)^2 = (dc)^2 --> (a^2+b^2) * d^2 =c^2 * d^2 d的取值是任意的,所以存在多个勾股数组 本源勾股数组 本源勾股数组是一个三元组(a,b,c),其中a,b,c只存在公因数1,且满足a^2 + b^2 = c^2 积累数据:下面的一些本源勾股数组 (3,4

「整理」勾股数组

我们大概老早就知道勾股定理,它大概就长这样: \[a^2+b^2=c^2\] 嗯,的确够简单的. 而且我们清楚地知道它的一个基本应用--知道\(Rt\Delta\)的两边长,求第三边.这大概初一就学了. 对于不知道勾股定理的童鞋们,不了解没关系,因为这里没有三角形,也不是探讨怎么求第三边,我们只探讨勾股数组. 这里的\(a \equiv b(mod\ c)\)其实就是\(a\%c=b\%c\),a|b其实就是\(b\%a=0\),希望小白们不要看不懂. 如果真的看不懂,可以先学习同余.约数.素数

勾股数组 学习笔记

颓废了一个暑假,想做点CF提高一下智商,然后就被这题卡住了.    http://codeforces.com/contest/707/problem/C 题目大意是给出各条边都是正整数的直角三角形的一条边长,求另外两条边可能的一种方案. 除了爆搜脑子一片空白,然后就很没志气的看了题解,提到了勾股数组,于是学习了一下.网络上的资料感觉证明不是详细,所以自己来写个总结. 1.首先如果 $a^2+b^2=c^2$ , 则$(ka)^2+(kb)^2=(kc)^2$ , 因此我们先只考虑$gcd(a,

勾股数组【学习笔记】

本原勾股数组(简写为PPT)是一个三元组(a,b,c),其中a,b,c没有公因数,且满足.例如下面是一项本原勾股数组: (3,4, 5),(5,12,13),(8,15,17),(7,24,25),(9,40,41),(11,60,61),(28,45,56),(33,56,65). 由这个短表容易得到一些结论,例如,似乎a与b奇偶性不同且c总是奇数. 证明如下: 若a与b都是偶数,则c也是偶数,意味着a,b,c有公因数2,所以三元组不是本原的,其次,若a,b都是奇数,那么c必然是偶数,这样假设

Fermat vs. Pythagoras POJ - 1305 (数论之勾股数组(毕达哥拉斯三元组))

题意:(a, b, c)为a2+b2=c2的一个解,那么求gcd(a, b, c)=1的组数,并且a<b<c<=n,和不为解中所含数字的个数,比如在n等于10时,为1, 2, 7,9则输出4. 好了!把所用知识点说一下: 数论之勾股数组(毕达哥拉斯三元组) 本原勾股数组(a,b,c)(a为奇数,b偶数)都可由如下公式得出:a=st,b=(s2-t2)/2, c = (s2+t2)/2, 其中s>t>=1是没有公因数的奇数. 再把勾股数公式拿过来: 套路一: 当a为大于1的奇数

bzoj 1041: [HAOI2008]圆上的整点 本原勾股數組

1041: [HAOI2008]圆上的整点 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2027  Solved: 853[Submit][Status] Description 求一个给定的圆(x^2+y^2=r^2),在圆周上有多少个点的坐标是整数. Input r Output 整点个数 Sample Input 4 Sample Output 4 HINT n<=2000 000 000 Source 這道題可用本原勾股數組解,由於本原

UVa 106 - Fermat vs Pythagoras(数论题目)

题目来源:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=3&page=show_problem&problem=42  Fermat vs. Pythagoras  Background Computer generated and assisted proofs and verification occupy a small niche in the realm

projecteuler----&gt;problem=9----Special Pythagorean triplet

title: A Pythagorean triplet is a set of three natural numbers, a b c, for which, a2 + b2 = c2 For example, 32 + 42 = 9 + 16 = 25 = 52. There exists exactly one Pythagorean triplet for which a + b + c = 1000. Find the product abc. 翻译: 勾股数组就是三个自然数a, b