分析:這道題初看起來第一感覺就是用暴力破解應該可以搞定,但是時間複雜度應該會相當可觀,仔細觀察,會發現這道題無非是全排列的一種運用,把等式定義為:
n=a+b/c ,則abc組合在一起就是1到9的乙個全排列,所以可以把問題轉換成對於乙個9位數的數字,如何將其劃分為a、b、c三部分,使得其滿足n=a+b/c(隱含條件:
b%c==0),對於乙個9位數可以這樣考慮:a是不可能大於n的,所以a的位數只可能是從1位到和n相同位數這個範圍,確定了a的位數之後,剩下的就是b和c的總位數,
b數字的開始位置即a數字的下一位,c數字的最後一位就是整個9位數的最後一位,那如何確定b的結束位置呢?
這裡有個小技巧,可以大大減少可能性的判斷:
假設a的結束位置為 aend,則aend+1~9就是b和c的位置,在這個位置範圍內,b最少佔據了一半的數字,否則b/c就不能整除了,所以可以從aend+1~9的中間位置開始
確定b的結束位置,這時候可以從中間位置開始向後確定b的結束位置,一直到8的位置,確定了b的結束位置,則a、b、c三個數字的具體值就都可以確定了,判斷是否符
合等式n=a+b/c,符合則輸出。
以上確定b的結束位置的方法其實不怎麼好,因為還是會浪費一些時間(自己模擬下就知道了),不過已經可以在規定的時間內得出答案了。
這裡再介紹一種確定b結束位置的方法,可以讓效能再提高一些:
觀察等式:n=a+b/c,可以轉換成==》b=(n-a)*c,n和a確定了(先確定a的結束位置後,再來確定b的結束位置的),c的最後乙個數字確定了(整個9位數最後一位),即可以確定b最後乙個數字了(這裡將其定義為bl),這樣可以從以上的aend+1~9的中間位置開始找,直到8,當數字為bl時,則判讀是否符合等式:n=a+b/c,可以想想,其實這種等於bl的位置至多有一次(因為數字1到9不能重複出現),所以第一次找到和bl匹配的數字的時候就不用再往後找了。用這種方法,提高的效能還是非常可觀的!
according to :
1 #include 2 #include 3 #include 4view code5int number, n = 0;6
int list[9] = ;78
inttest;910
void swap(int *a, int *b)
1116
17int getnum(int s, int
an)18
24return
num;25}
2627
void perm(int k, int m, int
x)28
47break;48
}49}50
51}5253}54
else
5562}63
}6465int
main()
6680 perm(0, 8
, x);
81 printf("
total:%d\n
", n);
82 s2 =clock();
83 printf("
%f ms\n
", (double)(s2 -s1));84}
85 }
帶分數(藍橋杯第四屆)
7 3 帶分數 qdulq 16 分 100 可以表示為帶分數的形式 100 3 69258 714 還可以表示為 100 82 3546 197 注意特徵 帶分數中,數字1 9分別出現且只出現一次 不包含0 類似這樣的帶分數,100 有 11 種表示法。從標準輸入讀入乙個正整數n n 1000 1...
帶分數 第四屆藍橋杯省賽C B C組
1.先列舉全排列 2.列舉位數 3.判斷是否滿足要求 這道題也就是n a b c,求出符合要求的abc的方案數。進行優化時,可以對等式進行改寫,改寫成 b cn ca。include include include includeusing namespace std const int n 30 ...
藍橋杯 2023年第四屆真題 帶分數 全排列
題目描述 100 可以表示為帶分數的形式 100 3 69258 714。還可以表示為 100 82 3546 197。注意特徵 帶分數中,數字1 9分別出現且只出現一次 不包含0 類似這樣的帶分數,100 有 11 種表示法。輸入從標準輸入讀入乙個正整數n n 1000 1000 輸出程式輸出該數...