WooKinson

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
问题描述

100 可以表示为带分数的形式:100 = 3 + 69258 / 714。

还可以表示为:100 = 82 + 3546 / 197。

注意特征:带分数中,数字1~9分别出现且只出现一次(不包含0)。

类似这样的带分数,100 有 11 种表示法。

输入格式

从标准输入读入一个正整数N (N<1000*1000)

输出格式

程序输出该数字用数码1~9不重复不遗漏地组成带分数表示的全部种数。

注意:不要求输出每个表示,只统计有多少表示法!

样例输入1
100
样例输出1
11
样例输入2
105
样例输出2
6
 
 记:
题目的类型是:n = a + b/c,求满足的个数
一开始以为就是简单的两个不同比例的"数字+分数"模式,结果在测试其他数据时错误,
故将注意力放在a,b,c的比例分配(隐藏条件b >= c)
然而并没有发现规律...
上网查阅,有一篇博客讲到了全排序(http://blog.csdn.net/jopus/article/details/18998403)
还没开始精细阅读源码,被其中的分区的概念刺激
于是有了思路:
  1. a的默认比例为1,依次递增(a <= n的长度)
  2. 将区间总长度(LEN=9)减去a,并取得中值,从而得到b,c的值(b >= c)
  3. 每次dfs后,b ++,c --,再次dfs(当b-c > n的长度时,明显不符条件)

 

源码如下:

 1 #include <stdio.h>
 2 #define LEN 9
 3 
 4 int n;
 5 int a,b,c;
 6 int sum = 0 , len = 0;
 7 int ans[LEN+1] = {0};
 8 int num[LEN+1] = {0,1,2,3,4,5,6,7,8,9,};
 9 int f[LEN+1] = {0};
10 
11 void dfs(int x)
12 {
13     int i , j;
14     int x1,x2,x3;            
15     if (x > 9)
16     {
17         x = x1 = x2 = x3 = 0;                
18         /*1.确定第一个值x1*/
19         for (i = 0 , j = 1 ; i < a ; i ++)
20         {            
21             x1 += ans[++x]*j;
22             j *= 10;
23         }        
24         
25         /*2.确定分数的分子x2*/
26         for (i = 0 , j = 1 ; i < b ; i ++)
27         {
28             x2 += ans[++x]*j;
29             j *= 10;
30         }
31         
32         /*3.确定分数的分母x3*/
33         for (i = 0 , j = 1 ; i < c ; i ++)
34         {
35             x3 += ans[++x]*j;
36             j *= 10;
37         }
38 
39         if (x2%x3 == 0 && (x1 + x2/x3) == n)
40         {
41             sum ++;
42             //printf("%d+%d/%d\n",x1,x2,x3);
43         }                
44         return ;
45     }
46     
47     for (i = 1 ; i <= 9 ; i ++)
48     {
49         if (!f[i])
50         {
51             ans[x] = num[i];
52             f[i] = 1;            
53             dfs(x+1);
54             f[i] = 0;
55         }
56     }        
57 
58     return ;
59 }
60 
61 int main(void)
62 {
63     int i;
64     scanf("%d",&n);        
65     i = n;
66     while(i)
67     {
68         i = i/10;
69         len ++;    /*获取n的长度*/
70     }
71     
72     for (a = 1 ; a <= len ; a ++)
73     {
74         i = LEN-a;
75         b = i - i/2;
76         c = i - b;
77         if (b < c)/*b必定为较大区间*/
78         {
79             b = b^c;
80             c = b^c;
81             b = b^c;
82         }
83         
84         /*更改b和c的比例*/
85         while (c)
86         {
87             dfs(1);
88             b ++;
89             c --;        
90         }
91     }    
92     printf("%d",sum);
93     return 0;
94 }

 

 

 
posted on 2018-03-12 21:14  WooKinson  阅读(371)  评论(0编辑  收藏  举报