UVa 10814 - Simplifying Fractions

题目:大整数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 --;
	}
}


你可能感兴趣的:(UVa 10814 - Simplifying Fractions)