第三届蓝桥杯省赛---带分数
带分数
100 可以表示为带分数的形式:100 = 3 + 69258 / 714
还可以表示为:100 = 82 + 3546 / 197
注意特征:带分数中,数字1~9分别出现且只出现一次(不包含0)。
类似这样的带分数,100 有 11 种表示法。
题目要求:
从标准输入读入一个正整数N (N<1000*1000)
程序输出该数字用数码1~9不重复不遗漏地组成带分数表示的全部种数。
注意:不要求输出每个表示,只统计有多少表示法!
例如:
用户输入:
100
程序输出:
11
再例如:
用户输入:
105
程序输出:
6
资源约定:
峰值内存消耗 < 64M
CPU消耗 < 3000ms
分析:dfs全排列+筛选数据+回溯,这里的筛选数据方法就是枚举两个端点,分成三个区间段判断x+(y/z)==n。。。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 7 int n; 8 int x=0,cnt=0; 9 int visited[10]; 10 int ans=0; 11 12 int getNum(int list[], int f, int r){ 13 int num=0; 14 for( int i=f; i<=r; i++ ){ 15 num=list[i]+num*10;;//进位 16 } 17 return num; 18 } 19 20 /*筛选正确的数据,划分区间*/ 21 22 int test(int a[]){ 23 int t=0; 24 //枚举左端点 25 for( int i=1; i<=x; i++ ){ 26 double x=0,y=0,z=0; 27 for( int j=i+1; j<9; j++ ){ 28 int k1=i+1; 29 int k2=j+1; 30 //求值 31 x=getNum(a,1,k1-1); 32 y=getNum(a,k1,k2-1); 33 z=getNum(a,k2,9); 34 if(x+(y/z)==n) t++; 35 } 36 } 37 return t; 38 } 39 40 /*dfs全排列*/ 41 void dfs(int k,int a[]){ 42 if(k==10){ 43 int tt=test(a); 44 if(tt){ 45 ans+=tt; 46 } 47 return ; 48 } 49 50 for( int i=1; i<=9; i++ ){ 51 if(!visited[i]){ 52 a[k]=i; 53 visited[i]=1;//标记这个数已经用过 54 dfs(k+1,a); 55 a[k]=0;//回溯 56 visited[i]=0;//回溯标记这个数已经用过 57 } 58 } 59 } 60 61 int main(){ 62 cin>>n; 63 int temp=n; 64 while(temp!=0){ 65 x++; 66 temp/=10; 67 } 68 int a[10]; 69 memset(visited,0,sizeof(visited)); 70 71 dfs(1,a); 72 cout<<ans<<endl; 73 74 return 0; 75 }
有些目标看似很遥远,但只要付出足够多的努力,这一切总有可能实现!