第三届蓝桥杯省赛---带分数

带分数

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 }
有些目标看似很遥远,但只要付出足够多的努力,这一切总有可能实现!
原文地址:https://www.cnblogs.com/Bravewtz/p/10433480.html