(Hankson的逆问题)

标题@[TOC]

(Hankson的逆问题)

一、题目名称: Hankson的逆问题

二、题目内容: 已知正整数a0,a1,b0,b1,设某未知正整数x满足:1.x和a0的最大公因数是a1,x和b0的最小公倍数是b1. Hankson的逆问题就是求出满足条件的数的个数。

三、算法设计:

1.首先设计求最大公因数和最小公倍数的算法

1.1.利用辗转相除法求两个数的最大公因数

前提:设两数为a,b设其中a 做被除数,b做除数,temp为余数

1.1.1大数放a中、小数放b中;

1.1.2求a/b的余数;

1.1.3若temp=0则b为最大公约数;

1.1.4如果temp!=0则把b的值给a、temp的值给a;

1.1.5返回第二步;

1.2求最小公倍数

两数相乘除以最大公因数即为最小公倍数

2.对于求x的个数

用枚举法,枚举从a1-b1的数,如果这个数同时满足1.x和a0的最大公因数是a1,x和b0的最小公倍数是b1.用count统计x的个数。
附上代码:

#include<iostream>
using namespace std;
int yinshu(int a,int b)
{
 int  temp;          //定义整型变量
  if(a<b)             //通过比较求出两个数中的最大值和最小值
    { temp=a;a=b;b=temp;} //设置中间变量进行两数交换
   while(b!=0)           //通过循环求两数的余数,直到余数为0
    {
      temp=a%b;
      a=b;              //变量数值交换
      b=temp;
    }
  return a;      
}
int beishu(int a,int b)
{
 //return a*b/yinshu(a,b);
 int temp;
  temp=yinshu(a,b);  //再次调用自定义函数,求出最大公约数
  return  (a*b/temp);
}
int qiux(int ai,int aj,int bi,int bj)//计算满足条件的x的个数 
{
 int count=0;//x的值 
 for(int i=aj;i<=bj;i++)//枚举不小于其最大公因数到不大于最大公倍数的数 
 {
 if(yinshu(i,ai)==aj)//满足x,a0的最大公因数为a1 
 {
  if(beishu(i,bi)==bj)//满足x,b0的最小公倍数为b1 
  count++;//x值加一 
  } 
 }
 return count;//返回x的值 
}
int main()
{
 
 int times;//需要计算的数据组数 
 cout<<"请输入需要计算的数据组数:"<<endl;
 cin>>times;// 输入需要计算的数据组数
 int a0[times],a1[times],b0[times],b1[times];
 cout<<"请依次输入数据,每一组以空格隔开,以回车结束"<<endl;
 for(int i=0;i<times;i++)//依次输入 
 {cin>>a0[i]>>a1[i]>>b0[i]>>b1[i];
 if((a0[i]<a1[i])||(b0[i]>b1[i])||(a0[i]%a1[i]!=0)||(b1[i]%b0[i]!=0))//对数据进行正确性判断 
   {
  cout<<"输入有误,每一组数第一个数要能被第二个数整除,第四个数要能被第三个数整除!请重新输入:";
 cin>>a0[i]>>a1[i]>>b0[i]>>b1[i];//重新输入 
 }
 }
 for(int i=0;i<times;i++)
  cout<<qiux(a0[i],a1[i],b0[i],b1[i])<<endl;//输出结果 
 return 0;
}

运行结果:
在这里插入图片描述

评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值