1. 程式人生 > >藍橋杯 帶分數

藍橋杯 帶分數

turn 出現一次 正整數 ++ 形式 () 無限 using 是否

100 可以表示為帶分數的形式:100 = 3 + 69258 / 714。
還可以表示為:100 = 82 + 3546 / 197。
註意特征:帶分數中,數字1~9分別出現且只出現一次(不包含0)。
類似這樣的帶分數,100 有 11 種表示法。

從標準輸入讀入一個正整數N (N<1000*1000)

程序輸出該數字用數碼1~9不重復不遺漏地組成帶分數表示的全部種數。

註意:不要求輸出每個表示,只統計有多少表示法!

看到這個題,想著用vis標記是否出現。但是感覺後面的分數可以無限改變形式,就沒思路了

看了題解,感覺好厲害。

首先 因為1~9出現且都僅出現一次,可以去全排列

然後分為3部分,第一部分最多到7,第二部分最多到8,第三部分到最後

然後就可以寫了。復雜度不會分析,

從 dfs(0,0)開始,表示從0位置,劃分第1部分

然後用雙層for枚舉

其實就是這樣的

1 -2-3456789

1-23-456789

……

1-2345678-9

12-3-456789

……

1234567-8-9

……

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<algorithm>
 4 using namespace std;
5 6 int a[9]={1,2,3,4,5,6,7,8,9}; 7 int ans,num[3],n; 8 9 void dfs(int cur,int cnt) { 10 if(cnt>1) { 11 int sum=0; 12 for(int i=cur;i<9;i++) sum=sum*10+a[i]; 13 num[cnt]=sum; 14 if(num[1]%num[2]==0&&num[0]+num[1]/num[2]==n) ans++; 15 return
; 16 } 17 int dd=6+cnt; 18 for(int i=cur;i<=dd;i++) { 19 num[cnt]=0; 20 int sum=0; 21 for(int j=cur;j<=i;j++) { 22 sum=sum*10+a[j]; 23 } 24 num[cnt]=sum; 25 dfs(i+1,cnt+1); 26 } 27 } 28 29 int main() { 30 while(~scanf("%d",&n)) { 31 ans=0; 32 sort(a,a+9); 33 do{ 34 dfs(0,0); 35 }while(next_permutation(a,a+9)); 36 printf("%d\n",ans); 37 } 38 }

藍橋杯 帶分數