如何解决计算大整数的最大公约数的二进制算法
为了计算两个大整数的GCD,我使用了二进制算法,将大整数保存在数组中,以高效计算两个大整数的GCD。
输入
一行包含两个整数 a 和 b,其中 0
时间限制
1 秒
样本输入 1
20210208 80201202
样本输出 1
6
样本输入 2
987654321987654321987654321 123456789123456789123456789
样本输出 2
9000000009000000009
我尝试过最坏的情况,比如 10^256 - 1 和 1,可以在 1 秒内计算出来。还 , 我已经通过了样本测试和其他一些测试数据。但是,当我将下面的代码上传到判断系统时,大多数测试数据显示TLE,甚至很少显示WA。我的代码有什么问题?还有其他更糟糕的情况我错过了吗?
pseudo code of Binary Algorithm
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#define SIZE 256
void rev(char *string,int len);
bool zero(int *to_array,int size);
void divided_by_2(int *ptr,int size);
bool comparison(int *m,int *n,int size);
void substraction(int *m,int size);
void twice(int array[],int k,int size);
int main(void){
char string_1[SIZE],string_2[SIZE];
scanf("%s%s",string_1,string_2);
int len_a = strlen(string_1);
int len_b = strlen(string_2);
char string_a[len_a],string_b[len_b];
strcpy(string_a,string_1);
strcpy(string_b,string_2);
/*reverse the string*/
rev(string_a,len_a);
rev(string_b,len_b);
int max_size = len_a;
if (len_b > len_a)
max_size = len_b;
int a[max_size],b[max_size];
for (int i = 0; i < max_size; i++){
if (i >= len_a)
a[i] = 0;
else
a[i] = string_a[i] - '0';
}
for (int i = 0; i < max_size; i++){
if (i >= len_b)
b[i] = 0;
else
b[i] = string_b[i] - '0';
}
int k = 0; /* k for power*/
int *m = a,*n = b;
/*binary algorithm for GCD */
while(!zero(m,max_size) && !zero(n,max_size)){
if (m[0] % 2 == 0 && n[0] % 2 == 0){
k++;
divided_by_2(m,max_size);
divided_by_2(n,max_size);
}else if (m[0] % 2 == 0)
divided_by_2(m,max_size);
else if (n[0] % 2 == 0)
divided_by_2(n,max_size);
if (comparison(n,m,max_size)){
int *temp = n;
n = m;
m = temp;
}
substraction(m,n,max_size);
}
twice(n,k,max_size);
bool zero = true;
for (int i = (max_size - 1); i >= 0; i--){
if (n[i] != 0 && zero)
zero = false;
if (!zero)
printf("%d",n[i]);
}
return 0;
}
void rev(char string[],int len){
char rev[len];
for (int i = 0; i < len; i++){
rev[i] = string[len - i - 1];
}
for (int i = 0; i < len; i++){
string[i] = rev[i];
}
}
bool zero(int *to_array,int size){
for (int i = 0; i < size; i++){
if (to_array[i] != 0)
return false;
}
return true;
}
void twice(int *array,int size){
int carry = 0;
for (int i = 0; i < k; i++)
for (int index = 0; index < size; index++){
int digit = array[index];
if (digit == 0 && carry == 0)
continue;
digit *= 2;
digit += carry;
if (digit >= 10){
array[index] = digit % 10;
carry = digit / 10;
}else{
array[index] = digit;
carry = 0;
}
}
}
void divided_by_2(int *ptr,int size){
int digit = ptr[0];
for (int index = 0; index < size; index++){
if (index == size - 1){
ptr[index] = digit / 2;
break;
}
int prev = ptr[index + 1];
if (prev % 2 == 0)
ptr[index] = digit / 2;
else{
ptr[index] = (digit + 10) / 2;
ptr[index + 1] -= 1;
}
digit = ptr[index + 1];
}
}
bool comparison(int *m,int size){
bool larger = false;
for (int index = 0; index < size; index++){
if (m[index] > n[index])
larger = true;
else if (n[index] > m[index]){
larger = false;
}
}
return larger;
}
void substraction(int *m,int size){
int borrow = 0;
for (int i = 0; i < size; i++){
int digit = m[i] - n[i];
digit -= borrow;
if (digit >= 0){
m[i] = digit;
borrow = 0;
}else{
m[i] = digit + 10;
borrow = 1;
}
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。