小數化分數2-- 2007省賽集訓隊練習賽(2)

小數化分數
Ray在數學課上聽老師說,任何小數都能表示成分數的形式,他開始了化了起來,很快他就完成了,但他又想到一個問題,如何把一個循環小數化成分數呢?
請你寫一個程序不但可以將普通小數化成最簡分數,也可以把循環小數化成最簡分數。

輸入
第一行是一個整數N,表示有多少組數據。
每組數據只有一個純小數,也就是整數部分爲0。小數的位數不超過9位,循環部分用()括起來。
輸出
對每一個對應的小數化成最簡分數後輸出,佔一行。

樣例輸入
3
0.(4)
0.5
0.32(692307)
樣例輸出
4/9
1/2
17/52

AC代碼

/*
教訓:
一定要多列出幾個例子,不能只列出一兩個例子,容易出錯,耽誤時間!
解題思路:
有限小數
0.1 = 1/10;
0.2 = 2/10;
0.88 = 88/100;

循環小數
0.(1) = 1/9;
0.(123) = 123/999 = 41/333;
0.(2132) = 2132/9999;

混循環小數
0.3(4) = 3/10 + 4/90;
0.33(4) = 33/100 + 4/900; 
0.33(44) = 33/100 + 44/9900
記錄,開始寫錯了,一定要多列出幾個,當時只列出了兩個混循環小數,以爲第二個分母只是90,900,90000之類
沒想到是9900,900,99990,之類的規律

公式
0.a(b) = a/(10^a.length) + b/(9...9*10^a..length)
此處9的數量取決於混循環小數的位數

*/

#include <cstdio>
#include <cstring>
#include <iostream>
#include <string>
#include <sstream>
#include <cmath>
using namespace std;

string num;

//求有幾個9,例如參數爲2則返回99
long long getNine(int size) 
{
	int n = 0;
	while (size--)
	{
		n = n * 10 + 9;
	}
	return n;
}
//求公約數
long long getYue(long long num1, long long num2)
{
	long long tmp;
	if (num1 < num2)
	{
		tmp = num1;
		num1 = num2;
		num2 = tmp;
	}
	while (num2 != 0)
	{
		tmp = num1 % num2;
		num1 = num2;
		num2 = tmp;
	}
	return num1;
}
//求公倍數
long long getBei(long long num1, long long num2)
{
	long long yue = getYue(num1, num2);
	return num1 *num2 / yue;
}

int main()
{
	int n;
	cin >> n;
	while (n--)
	{
		string a, b;
		cin >> num;
		int i;
		for (i = 2; i < num.length(); i++)
		{
			if (num[i] != '(')
			{
				a += num[i];
			}
			else break;
		}

		for (i++; i < num.length(); i++)
		{
			if (num[i] != ')')
			{
				b += num[i];
			}
			else break;
		}
		
		//其實,有限小數,循環小數,還有混循環小數可以寫在一起,這個就交給你們了!!!加油!!!朕乏了~
		if (a.length() != 0 && b.length() != 0)//a,b同時不爲0的情況,最複雜
		{
			//公式 0.a(b) = a / (10 ^ a.length) + b / (9...9 * 10 ^ a..length)
			/*
			混循環小數
			0.3(4) = 3/10 + 4/90;
			0.33(4) = 33/100 + 4/900; 
			0.33(44) = 33/100 + 44/9900
			*/
			long long numA, numB;
			//字符串轉換成數字
			stringstream turnA, turnB;
			turnA << a; turnA >> numA;
			turnB << b; turnB >> numB;

			long long numAF = pow(10, a.length());
			long long numBF = getNine(b.length()) * pow(10, a.length());

			//求出分母最小公倍數,方便計算兩個分數的和
			long long zuiXiaoGongBeiShu = getBei(numAF, numBF);
			long long beiA = zuiXiaoGongBeiShu / numAF;
			long long beiB = zuiXiaoGongBeiShu / numBF;

			numA = beiA * numA;
			numAF = beiA *numAF;
			numB = beiB * numB;
			numBF = beiB * numBF;
			
			//兩分數相加
			long long fenzi = numA + numB;
			long long fenmu = numAF;

			long long yueFenShu = getYue(fenzi, fenmu);


			cout << fenzi / yueFenShu << "/" << fenmu / yueFenShu << endl;;


		}
		else if (a.length() == 0 && b.length() != 0)
		{
			long long numB;
			stringstream turnB;
			turnB << b;
			turnB >> numB;

			long long numBF = getNine(b.length());

			long long yue = getYue(numB, numBF);
			numB = numB / yue;
			numBF = numBF / yue;
			
			cout << numB << "/" << numBF << endl;
		}
		else if (a.length() != 0 && b.length() == 0)
		{
			long long numA;
			stringstream turnA;
			turnA << a;
			turnA >> numA;

			long long numAF = pow(10, a.length());

			long long yue = getYue(numA, numAF);
			numA = numA / yue;
			numAF = numAF / yue;

			cout << numA << "/" << numAF << endl;
		}
	}
	
	return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章