1. 程式人生 > >演算法的樂趣c/c++ —— 1.2.1入門習題

演算法的樂趣c/c++ —— 1.2.1入門習題

宣告:摘選自“ 演算法競賽入門經典(第2版)”作者:  劉汝佳  /  陳鋒   ISBN:9787302291077

迴圈小數

輸入整數a和b(0≤a≤3000,1≤b≤3000),輸出a/b的迴圈小數表示以及迴圈節長度。 例如a=5,b=43,小數表示為0.(116279069767441860465),迴圈節長度為21。

解題思路:

5/43,就算是double型別的變數小數點後也只有幾位數字,完全不能達到我們的要求。那麼我們就採用以小見大的方法,50/43、500/43、5000/43、、、這樣肯定能夠得到我們需要的答案。但是需要將除數擴大多少倍才可以呢?我們可以根據算數運算規則來看:5/43 ≈ 0.116。0=5/43 取整;  1=(5*10%43)*10 /43 就是5擴大10倍取餘43即70/43取整;即

\frac{5}{43} => \tfrac{5*10}{43} => \tfrac{43+7}{43} => 1+\tfrac{7*10}{43} => 1+1+\tfrac{27*10}{43} => 1+1+6+\tfrac{12*10}{43}

讀取迴圈節長度就設定一個標誌位,迴圈一次,標誌位就 +1 。如何結束迴圈呢?就是看餘數,如果後面的餘數等於最初第一個餘數,說明接下來就會重複剛剛的計算過程了,那麼這就說明我們已經找到第二個迴圈了。可以結束計算過程了。

#include<stdio.h>
int main()
{
	int a, b, H, L, m, i=0;    //a,b為輸入的數字,H為a/b的整數部分,L為a%b的餘數部分, m為標誌位, i用於記錄迴圈節長度 
	scanf("%d%d", &a, &b);     //輸入數字a,b 
	printf("%d.(", a/b);       //先列印整數部分加上一個半括號。例如: 0.( 
	L = a % b;                 //L初始等於a%b。 後續會繼續對L進行賦值,以便不斷進行除法操作  
	m = L;                     //將m賦值L,如果後續出現m得值等於不斷賦值後的L,說明我們已經開始進入下一個迴圈了 
	while(1)
	{
		H = L*10 / b;          //H用於存放需要列印的整數部分,5/43=0.1,但是打印不出0.1怎麼辦?那就將5擴大10倍列印 1, 
		L = L*10 % b;          //L已經取餘一次了,再取餘肯定還是不變的,為了求取下一位數字,那麼就需要將小數點右移一位,即擴大10倍 
		printf("%d", H);
		i += 1;                // i用於記錄小數點後的位數 
		if(m==L) break;        //如果出現m得值等於不斷賦值後的L,說明我們已經開始進入迴圈了 ,這就是我們結束while的條件 
	}
	printf(") %d",i);          //列印整一個半括號跟迴圈節長度。例如: ) 21 
}