2013年1月31日 星期四

[C/Java] Armstrong數

當一個三位的正整數符合a^3+b^3+c^3 = abc的條件,
即各位數本身的立方和等於這個三位數時,
我們將其稱之為Armstrong數。(三位的Armstrong數)
試寫一個程式求出所有的三位Armstrong數。

解:
之前在讀Java的時候有習題出過,
就試解了一下,
Code如下:
public class Armstrong{
	public static void main(String[] args){
		int h,t,o,sum;
		for(int i = 100; i <= 999; i++){
			h = i / 100; 
			t = (i / 10) % 10;
			o = i % 10;
			sum = h*h*h + t*t*t + o*o*o;
			if(sum == i) System.out.println(i);
		}
	
	}
}
這樣寫當然是沒有問題,
根本概念是一個一個check每一個數是否等同於各位數的立方和,
但,每一次換位都要重新計算,不覺得太浪費時間了嗎?
按照書上給的概念的話,解法如下:(C語言)
int main(int argc, char *argv[])
{
	int p,q,r,p_cube,q_cube,r_cube;
	int p100,q10;
	int number,sum;
	int count = 0;
	for(p = 1, p100 = 100; p <= 9; p++, p100+=100)
	{
		p_cube = p*p*p;
		for(q = q10 = 0; q <= 9; q++, q10+=10)
		{
			q_cube = q*q*q;
			for(r = 0; r <= 9; r++)
			{
				r_cube = r*r*r;
				number = p100 + q10 + r;
				sum = p_cube + q_cube + r_cube;
				if(number == sum)
					printf("\n%3d%9d", ++count, number);
			}
		}
	
	}
	printf("\n\nTotal Count: %d\n", count);
	system("PAUSE");
	return 0;
}
這個解法同樣有相同的問題存在。
它在換位的時候依然會重算,只有在高位不動的狀況下不會重計。
如果是以速度考量的話,可以擔負10個int大小來存放0~9的三次方。
更改如下:
int main(int argc, char *argv[])
{
	int p,q,r;
	int p100,q10;
	int number,sum;
	int count;
	int* cube = (int*)malloc(sizeof(int)*10);
	cube[0] = 0; cube[1] = 1;
	for(count = 2; count <= 9; count++)
		cube[count] = count*count*count;
	count = 0;
	for(p = 1, p100 = 100; p <= 9; p++, p100+=100)
		for(q = q10 = 0; q <= 9; q++, q10+=10)
			for(r = 0; r <= 9; r++)
			{
				number = p100 + q10 + r;
				sum = cube[p] + cube[q] + cube[r];
				if(number == sum)
					printf("\n%3d%9d", ++count, number);
			}
	printf("\n\nTotal Count: %d\n", count);
	system("PAUSE");
	return 0;
}
不但省下了每次的重新計算,同時實際增加的單位只有7個int而已。
(因為p_cube~r_cube省掉了)

沒有留言:

張貼留言