HDU 6441 2018中国大学生程序设计竞赛 - 网络选拔赛 1004 Find Integer

版权声明:《学习技巧》每次使用单边大脑的时间不要太久,连续使用左边大脑30分钟就如同连续使用左臂30分钟一样,周期性的交换让大脑两侧能够轮流休息,左脑活动包括了循序渐进的工作,解决逻辑问题与分析,而右脑活动包括了隐喻,创造性思考,模式匹配和可视化。 https://blog.csdn.net/intmainhhh/article/details/82055498

主要用到了毕达哥斯拉三元组1004 Find Integer
Problem
people in USSS love math very much, and there is a famous math problem .
give you two integers , ,you are required to find integers , such that a^n+b^n=c^n
Input
one line contains one integer T;(1<=T<=1000000)
next lines contains two integers n,a; (0 ≤ n ≤ 1000 000 000,3 ≤ a ≤ 40000)
Output
print two integers b,c, if  b,c exits; (1<=b,c<=1000 000 000)
else print two integers -1 -1 instead.
Sample Input
1

2 3

Sample Output
4 5

方法1 :伪代码如下:

a*a=(c-b)*(c+b)

if (a是奇数),则令c-b=1,c+b=a*a;           则c=(a*a+1)/2,b=c-1;

else               则令c-b=2,c+b=a*a/2;        则c=(a*a/2+2)/2,b=c-2;

ac代码如下

#include <bits/stdc++.h>
#define ll long long
using namespace std;
int main() {
    int t,a,n;
    ll b,c;
    scanf("%d",&t);
    while(t--) {
        scanf("%d%d",&n,&a);
        if(n>2 || n==0)
            puts("-1 -1");
        else if(n==1) {
            printf("1 %d",a+1);
        } else {
            if(a&1) {
                c=(a*a+1)/2;
                b=c-1;
            } else {
                c=(a*a/2+2)/2;
                b=c-2;
            }
            printf("%lld %lld\n",b,c);
        }

    }
}

方法2 

当 a 为奇数

a = 2 * k + 1;

c = k ^ 2 + (k + 1) ^ 2;

b = c - 1;

当 a 为偶数

a = 2 * k + 2;

c = 1 + (k + 1) ^ 2;

b = c - 2;

代码如下:

#include <bits/stdc++.h>
using namespace std;
#define ll long long
ll n, a, b, c;
int main()
{
    int T;
    scanf("%d", &T);
    while(T--){
        scanf("%lld%lld", &n, &a);
        if(n == 0 || n > 2){
            puts("-1 -1");
            continue;
        }
        if(n == 1){
            printf("%lld %lld\n", a, a<<1);
            continue;
        }
        if(a & 1){
            ll k = a / 2;
            c = k * k + (k + 1) * (k + 1);
            b = c - 1;
        }
        else{
            ll k = a / 2 - 1;
            c = 1 + (k + 1) * (k + 1);
            b = c - 2;
        }

        printf("%lld %lld\n", b, c);
    }

    return 0;
}

方法3

#include<bits/stdc++.h>///这题是费马大定理,但是abc都是int,所以n只能取0,1,2,大于2时无整数解,又因为 3<= a <=40000,所以n!=0
using namespace std;   ///所以n只能取1和2,当n==1时,随便找一个c-b=a就ok;当n==2时用毕达哥拉斯三元组
#define ll long long
const ll maxn = 1e6+10;
int main() {
    int t,a,n;
    long long b,c;
    scanf("%d",&t);
    while(t--) {
        scanf("%d%d",&n,&a);
        if(n>2 || n==0)
            puts("-1 -1");
        else if(n==1) {
            printf("1 %d",a+1);
        } else {
            for(ll i=1;; i++) {
                if((a*a-i*i)%(2*i)==0) {
                    b=(a*a-i*i)/(2*i);
                    c=b+i;
                    break;
                }
            }
            printf("%I64d %I64d\n",b,c);
        }

    }
}

关于毕达哥斯拉三元组的原文博客 点这里,也可以看下面的

本原勾股数组(PPT)是一个三元组(a,b,c),其中a,b,c无公因数,且满足a² +b² =c²。

很明显存在无穷多个勾股数组(abc同乘以n),下面研究abc没有公因数的情况,先写出一些本原勾股数组:

case:(3,4,5) (5,12,13) (8,15,17) (7,24,25) (20,21,29)(9,40,41)(12,35,37)(11,60,61)(28,45,53) (33,56,65) (16,63,65)

观察可以看出a,b奇偶性不同且c总是奇数。(用一点技巧可以证明这是正确的)

另外:

3² = 5² - 4² = (5-4)(5+4) = 1 × 9

15² = 17²-8² = (17-8)(17+8) = 9 ×25

35² = 37² - 12² = (37-12)(37+12) = 25 ×49

......

很神奇的是似乎c-b与c+b总是平方数,并且c-b与c+b木有公因数。证明一下下:假设有公因数,设d是c-b与c+b的公因数,则d也整除(c+b)+(c-b)=2c, (c+b)-(c-b) = 2b,所以d整除2c,2b,但是b,c木有公因数,又假设了(a,b,c)是本原勾股数组,从而d等于1或2,又因为d整除(c-b)(c+b)=a².a²是奇数,所以d = 1,c-b与c+b木有公因数。,又因为(c-b)(c+b)=a²,所以c-b与c+b的积是平方数,只有二者都是平方数才会出现(可以把二者分解成素数乘积直观地看出),令c+b = s²,c-b=t²,解得

c=(s²+t²)/2, b=(s²-t²)/2,a = √(c-b)(c+b) = st.这就得出了勾股数组定理:

每个本原勾股数组(a,b,c)(a为奇数,b偶数)都可由如下公式得出:a=st,b=(s²-t²)/2, c = (s²+t²)/2, 其中s>t>=1是没有公因数的奇数。

当取t=1时就可以得到上面的许多例子。

猜你喜欢

转载自blog.csdn.net/intmainhhh/article/details/82055498