POJ-1305(勾股定理)(Fermat vs. Pythagoras)

这个题目就是找在1~N之间互质的三个正整数x、y、z,并满足x^2+y^2=z^2,判断这样的数有多少对,以及跟1~N中与这些互质正整数无关的正整数的个数。
其实比较关键的是对上面那个式子 x^2+y^2=z^2 进行变形,减少一个变量为
(r^2-s^2)^2 + (2*r*s)^2 = (r^2+s^2)^2,
这样只有两个变量存在,可以减少一轮循环。于是题目就变成了找这样的r和s,当r*r + s*s <= n时,
z = r*r + s*s;
 y = max(r*r - s*s, 2*r*s);
 x = min(r*r - s*s, 2*r*s);

 此时,如果x、y、z互质,满足条件的正整数组计数就加1,同时把所有与这些数相关的数组位标记为1

#define MAXN 1000000
int flag[MAXN + 5];
int ans;
int gcd(int a, int b)
{
    return b == 0 ? a : gcd(b, a % b);
}
void process(int value)
{
    int i, j;
    for (j = 1; j * j <= value; ++j) {
        int minj = j - 1;//MY_MIN(sqrt(value * 1.0 - j * j) + 1, j - 1);
        for (i = 1; i <= minj; ++i) {
            if (gcd(i, j) == 1) {
                int x = j * j - i * i;
				if (x <= 0) break;
                int y = 2 * i * j;
                int z = j * j + i * i;
                if (x <= value && y <= value && z <= value) {
                    if (gcd(gcd(x, y), z) == 1)
                        ++ans;
                }
                else
                    break;
                int times = 1;
                while (x * times <= value && y * times <= value && z * times <= value) {
                    flag[x * times] = flag[y * times] = flag[z * times] = 1;
                    ++times;
                }
            }
        }
    }
}
int main()
{
    int n;
    while (cin>>n) {
        ans = 0;
        memset(flag, 0, sizeof(flag));
        int i;
        int sum = 0;
        process(n);
        for (i = 0; i <= n; ++i)
            if (flag[i])
                ++sum;
        printf("%d %d\n", ans, n - sum);
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值