【 OJ 】 HDOJ1058 18年12月22日20:00 [ 50 ]
阿新 • • 發佈:2018-12-23
這題找規律我想了很多試了有的感覺很煩,參考了人家的思路很....OJBnice,所以我按照人家的思路寫了一遍。
這題就是求醜數,醜數最小的因子由2,3,5,7組成,1 被定義為最小丑數
首先很重要的一點要說下,醜數一定是由醜數乘醜數所得 ( = =.)!! 醜數定義說的很明確因子只含有2,3,5,7
2357可以理解為這個是醜數的最小倍數,假設一個醜數x存在,那麼當前醜數x可以產生的醜數一定由乘2357產生,當前醜數x產
生的最小丑數不一定是當前序列所需要的....假設目前序列為 1 2 3 4 5 6 ,下一個需要的最小丑數為7(由1*7產生),但是6可以
產生的最小丑數一定是 6*2=12,但是12並不是當前序列所需要的最小丑數,就這個意思
所以解決方法就是:1和2357相乘會得到4個數(這4個數也是1所能產生的最小丑數),拿到4箇中最小的一個1*2,2已經被放進
序列,說明1*2已經用完了,但是剩下的357遲早會用到,不動它們。這時候讓2的指標index2去指向序列中的2的位置,因為2放
進了序列,這時候2也能產生4個最小的醜數,其他的不可能用到,因為2*(3.5.7)一定大於1*(3.5.7),但是2*2可能會被用到。
所以從2*2和1*3和1*5和1*7中選擇一個最小的數字,並放入序列,然後移動指標,重複N-1次得到第N個醜數
注:其中2*3 和3 *2因為都等於6所以說明序列2 和序列3 產生的都被使用,所以2 和 3 的指標index2 index3都需要指向序列的下一個
下面是AC程式碼:
# include<iostream> # include<algorithm> //# include<Windows.h> # define NMAX 10000 using namespace std; int Res[NMAX] = {1}; int MIN(int a, int b, int c,int d) { return min((min(a, b)), (min(c, d)));//返回最小值 } int main() { //long start_time = GetTickCount(); //獲取此程式段開始執行時間 int index, index2, index3, index5, index7; index2 = index3 = index5 = index7 = 0;//初始化為0 index = 1; int n; cin >> n; int temp; while (n) { while (index < n) { temp = MIN(Res[index2] * 2, Res[index3] * 3, Res[index5] * 5, Res[index7] * 7); if (temp == Res[index2] * 2)index2++; if (temp == Res[index3] * 3)index3++; if (temp == Res[index5] * 5)index5++; if (temp == Res[index7] * 7)index7++; Res[index++] = temp; } int m = n % 100; if(m==11||m==12||m==13) printf("The %dth humble number is %d.\n", n, Res[n-1]); else if(n%10==1) printf("The %dst humble number is %d.\n", n, Res[n-1]); else if(n%10==2) printf("The %dnd humble number is %d.\n", n, Res[n-1]); else if(n%10==3) printf("The %drd humble number is %d.\n", n, Res[n-1]); else printf("The %dth humble number is %d.\n", n, Res[n-1]); //n帶 11 12 13為th 剩下 1 st 2 nd 3 rd cin >> n; } // long end_time = GetTickCount(); //獲取此程式段開始執行時間 // cout << "程式段執行時間:" << (end_time - start_time) << "ms!" << endl; //差值即執行時間 system("pause"); return 0; }