UVa 10814 - Simplifying Fractions

来源:互联网 发布:知豆汽车是哪家公司的 编辑:程序博客网 时间:2024/06/06 02:47

题目:大整数gcd。

分析:模拟、大数运算。大整数模拟gcd,需要利用大整数乘法、除法和比较,除法使用试商法、即从最高位开始从9-0一次试乘,每位找到乘以除数后第一个小于被除数的数极即为商。

注意:边界数据、1000000000000000000000000000000 / 999999999999999999999999999999

#include <iostream>#include <cstdlib>#include <cstring>#include <stdio.h>using namespace std;char a_in[ 65 ];char b_in[ 65 ];int  a_ar[ 65 ];int  b_ar[ 65 ];int  a_tp[ 65 ];int  b_tp[ 65 ];int  divr[ 65 ];int  mulr[ 65 ];int  remr[ 65 ];void output( int *a ){int end = 30;while ( end >= 1 && !a[end] ) end --;while ( end >= 0 ) printf("%d",a[end --]);}int  cmp( int *a, int *b ){for ( int i = 60 ; i >= 0 ; -- i )if ( a[i] != b[i] )return a[i] - b[i];return 0;}void mul( int *a, int *b, int* c ){for ( int i = 0 ; i <= 60 ; ++ i )c[i] = 0;for ( int i = 0 ; i <= 30 ; ++ i )for ( int j = 0 ; j <= 30 ; ++ j )c[i+j] += a[i]*b[j];for ( int i = 0 ; i <= 60 ; ++ i ) {c[i+1] += c[i]/10;c[i] %= 10;}}void div( int *a, int *b, int* c ){for ( int i = 0 ; i <= 60 ; ++ i )c[i] = 0;for ( int i = 30 ; i >= 0 ; -- i )for ( int j = 9 ; j >= 0 ; -- j ) {c[i] = j;mul( b, c, mulr );if ( cmp( a, mulr ) >= 0 ) break;}}void mod( int *a, int *b, int *r ){for ( int i = 0 ; i <= 60 ; ++ i )r[i] = 0;div( a, b, divr );mul( b, divr, mulr );for ( int i = 0 ; i <= 60 ; ++ i )r[i] = a[i] - mulr[i];for ( int i = 0 ; i <= 60 ; ++ i )while ( r[i] < 0 ) {r[i+1] -= 1;r[i] += 10;}}void gcd( int *a, int *b ){int sum = 0;for ( int i = 0 ; i <= 30 ; ++ i )sum += b[i];if ( !sum ) return;mod( a, b, remr );for ( int i = 0 ; i <= 30 ; ++ i ) {a[i] = b[i];b[i] = remr[i];}gcd( a, b );}int main(){int  N;char c;while ( cin >> N ) for ( int t = 1 ; t <= N ; ++ t ) {cin >> a_in >> c >> b_in;for ( int i = 0 ; i <= 30 ; ++ i )a_ar[i] = b_ar[i] = 0;int L_a = strlen(a_in);for ( int i = 0 ; i < L_a ; ++ i ) {a_ar[i] = a_in[L_a-1-i]-'0';a_tp[i] = a_ar[i];}int L_b = strlen(b_in);for ( int i = 0 ; i < L_b ; ++ i ) {b_ar[i] = b_in[L_b-1-i]-'0';b_tp[i] = b_ar[i];}gcd( a_tp, b_tp );div( a_ar, a_tp, divr );output( divr );cout << " / ";div( b_ar, a_tp, divr );output( divr );cout << endl;}return 0;}
/*更快的大整数除法、移位减法*/void lmove( int *a ){for ( int i = 60 ; i > 0 ; -- i )a[i] = a[i-1];a[0] = 0;}void rmove( int *a ){for ( int i = 0 ; i < 60 ; ++ i )a[i] = a[i+1];}void div( int *a, int *b, int* c ){for ( int i = 0 ; i <= 60 ; ++ i ) {c[i] = 0;temb[i] = b[i];tema[i] = a[i];}int bits = 0;while ( cmp( temb, tema ) < 0 ) {bits ++;lmove( temb );}while ( bits >= 0 ) {while ( cmp( tema, temb ) >= 0 ) {c[ bits ] ++;for ( int i = 0 ; i < 60 ; ++ i )tema[i] -= temb[i];for ( int i = 0 ; i < 60 ; ++ i )while ( tema[i] < 0 ) {tema[i+1] -= 1;tema[i] += 10;}}rmove( temb );bits --;}}


原创粉丝点击