DHU OJ | 进阶练习17-公式求解 | 判断一个实数是否为整数

27 篇文章 1 订阅

17 公式求解

作者: 朱星垠时间限制: 10S章节: 循环

问题描述 :

明明刚上初中,数学课上老师教了平方的概念,即两个相同的数相乘可以表示为这个数的平方:a×a = a 2。明明觉得这很有趣,就开始研究起来,很快掌握了这个知识点。但是在一次考试中,明明遇到了一个难题,题目的要求是有四个正整数a、b、x、y,他们各自的平方数组成了一个等式a^2 + x^2 = b^2 + y^2,现在已知a和b,请求出所有小于等于100的x、y,来满足这个等式。例如给你a=2、b=5,我们可求出的解是x=5、y=2和x=11、y=10。 明明虽然明白了题目的意思,但是要自己求解却显得相当困难。他想了很久也没有能够解出这道题目。放学回家就开始问他的爸爸,他爸爸虽然对数学很精通,但是也无法一时给出正确的答案,于是他就求助于你,帮他解决这个问题。 明明的问题可以归结为:给定两个正整数a、b,求所有的正整数x和y,使a^2 + x^2 = b^2 + y^2,其中a、b、x、y都不大于100。在所有的有效解中,按x的大小进行排序,从小到大输出。

输入说明 :

你写的程序要求从标准输入设备中读入测试数据作为你所写程序的输入数据。标准输入设备中有多组测试数据:每组测试数据由一个不大于100的正整数a后跟一个不大于100的正整数b组成,a和b之间由一个空格分开,形成一行数据,其行首和行尾都没有任何空格,当a和b同时为0时,表示输入结束;每组测试数据与其后一组测试数据之间没有任何空行,第一组测试数据前面以及最后一组测试数据后面也都没有任何空行。

输出说明 :

对于每一组测试数据,你写的程序要求计算出一组或者多组相应的运算结果,并将这一组或者多组运算结果作为你所写程序的输出数据依次写入到标准输出设备中。每组运算结果由一个不大于100的正整数x后跟一个不大于100的正整数y组成,x和y之间由一个空格分开,形成一行数据,其行首和行尾都没有任何空格;如果有多组相应的运算结果,则按x的大小进行排序,从小到大输出。 每组运算结果与其后一组运算结果之间有一个空行,最后一组运算结果后面没有空行。 注:通常,显示屏为标准输出设备。

输入范例 :

2 5
3 4
0 0

输出范例:

5 2
11 10

4 3

笔记

需要注意几个条件:

  • y^2 = a^2-b^2+x^2,显然,a^2-b^2+x^2 ≥ 0;
  • x,y∈[1,100],且为整数;
  • a,b不可同时为0,因为当a、b同时为0时,x和可取任意值;

判断一个数是否为整数

假设有实数a,如何判断它是否是整数呢?

易知,若一个数是整数,则其小数部分为0。

可编码如下:

const double eps = 1e-8;
#define Equ(a,b) (fabs((a)-(b))<(eps))

int is_integer(double a){
	int integer = (int)a;                    //整数部分
	double decimal = a-(double)integer;    //小数部分
	if(Equ(decimal,0.00)){
		return 1;
	}else{
		return 0;
	}
}

宏定义

#define Equ(a,b) (fabs((a)-(b))<(eps))

为浮点数的判等,详见>>DHU OJ | 基本练习-21 计算e

代码

#include<stdio.h>
#include<math.h>

const double eps = 1e-8;
#define Equ(a,b) (fabs((a)-(b))<(eps))

//用一个结构体记录<x,y>对
struct data{
	int x;
	int y;
};

//判断实数a是否是整数
int is_integer(double a){
	int integer = (int)a;
	double decimal = a-(double)integer;
	if(Equ(decimal,0.00)){
		return 1;
	}else{
		return 0;
	}
}

int main(){
	int a,b;
	struct data d[101];    //使用结构体数组记录每一组结果
	int flag = 1;
	while(scanf("%d %d",&a,&b)!=EOF){
        //a和b不可同时取0
		if(a==0 && b==0) {
			continue;
		}
		int n = 0;
		int i;
		for(i=1;i<=100;i++){
			int x_t,y_2_t;
			x_t = i;
			y_2_t = a*a-b*b+x_t*x_t;
            //y^2必须大于等于零
			if(y_2_t>0 && is_integer(sqrt(1.0*y_2_t))){
				d[n].x = x_t;
				d[n].y = (int)sqrt(1.0*y_2_t);
				n++;
			}
		}
		
        //对结果进行排序
		int j;
		for(i=0;i<n;i++){
			int x_t = d[i].x;
			int y_t = d[i].y;
			for(j=i;j>0;j--){
				if(x_t<d[j-1].x){
					d[j].x = d[j-1].x;
					d[j].y = d[j-1].y;
				}else{
					d[j].x = x_t;
					d[j].y = y_t;
					break;
				}
			}
		}
		
		if(flag){
			flag = 0;
		}else{
			printf("\n\n");
		}
		for(i=0;i<n;i++){
			if(i>0){
				printf("\n");
			}
			printf("%d %d",d[i].x,d[i].y);
		}
	}
	
	return 0;
}

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值