实验D----两个数的互素判定

Problem description
称两个正整数是互素的,当它们没有大于1的公因子的时候。比如,4与9就是互素的,尽管4与9都不是素数,但4与9只有一个公因子:1,所以它们互素。但4与22就不是互素的,因为它们有一个大于1的公因子:2。
你的任务,给你2个数,判断它们是否互素。

Input
有多个测试序列,测试结束于测试文件结束;
每个测试序列占一行,每行2个用空格隔开的正整数a,b。a,b < 264.

Output
对于每对输入的整数,输出”YES”,如果它们互素;否则,输出”NO”。

Sample Input
22 4
4 9
Sample Output
NO
YES
 
解题思路:试除法虽然可以判断两个数是否互素,但肯定会超时;所以在这里使用辗转相除法,即欧几里得算法。
欧几里得算法E如下:
E=“对输入<x,y>,x和y是二进制表示的自然数:
1)重复下面的操作,指导y=0.
2)赋值x <- x mod y.
3)交换x和y的值。
4)输出x。”
简单来说是这样的:
x,y,r1,r2,r3......rn,0
r1=x%y, r2=y%r1, 以此类推。看最后rn是否为1
因为 x = k*y+r1 , 即 r1 = x - k*y 
(a,b)表示a 和 b 的最大公因子
那么 (x,y)一定是r1的因子,(y,r1)一定是x的因子
所以(x,y)==(y,r1)==(r1,r2)==......==(rn,0)==rn
当且仅当最大公因子为1,即rn==1时,x,y互素;否则不然。
 
当然,算法思想很简单,但这道题很不容易通过。原因在于输入:每行2个用空格隔开的正整数a,b。a,b < 264
输入的数可以达到2^64,而:

int -2147483648 ~ +2147483647 (4 Bytes) unsigned int 0 ~ 4294967295 (4 Bytes) long == int long long -9223372036854775808 ~ +9223372036854775807 (8 Bytes) double 1.7 * 10^308 (8 Bytes)

unsigned int 0~4294967295

__int64的最大值:9223372036854775807
__int64的最小值:-9223372036854775808
unsigned __int64的最大值:18446744073709551615
 
所以,比较合适的类型是unsigned __int64(注意下划线之前有空格!)
输入格式为scanf("%I64d",&a);
注意是大写的I而不是小写的l
 
用cin>>a不知道为什么不行~~!
 
代码如下:
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
using namespace std;

int main()
{
	unsigned __int64 a,b,r;
	//while(scanf("%l64d %l64d",&a,&b)!=EOF){
	  while(scanf("%I64u %I64u",&a,&b)!=EOF){//这个输入坑死爹啊!2^64意味着0啊,因为是64位的,但2^64表示64个0,第65位的那个1没有了!
		r=a%b;
	//	printf("a,b,r:\n");
	//	printf("%I64d,%I64d,%I64d\n",a,b,r);
		while(r!=0)
		{
			a=b;
			b=r;
			r=a%b;
		}
		if(b==1)
		{
			printf("YES\n");
		}
		else
			printf("NO\n");
	}
	return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值