蓝 桥 杯
带分数
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
请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意:不要使用package语句。不要使用jdk1.6及以上版本的特性。
注意:主类的名字必须是:Main,否则按无效代码处理。
题解:因为1~9需要每个数都用一遍,所以可以想到把1~9进行全排列,然后把这9个数划分为A,B,C三组,A的范围一定是小于n,两层for循环遍历,第一层for循环找A的范围,即A可以占1~9中的几位,第二层for循环遍历找B和C的范围,即B可以占的位数为A的下一位到j,C所占的位置是j+1到9,把这些位数加和,然后判断是否满足题意即可。
JAVA代码:
1 import java.util.Scanner;
2
3 public class Main{
4 static int n,ans = 0;
5 static int[] vis = new int [10];
6 static int[] num = new int [20];
7 static int getsum(int y, int x) {
8 int sum = 0;
9 for(int i=y;i<=x;i++) {
10 sum = sum*10 + num[i];
11 }
12 return sum;
13 }
14 static void check() {
15 for(int i=1;i<10;i++) {
16 int x = getsum(1,i);
17 if(x>=n)
18 break;
19 for(int j=i+1;j<10;j++) {
20 int b = getsum(i+1,j);
21 int c = getsum(j+1, 9);
22 if(c!=0&&b%c==0&&x+b/c==n)
23 ans++;
24 }
25 }
26 }
27 static void dfs(int step) {//对1~9进行全排列
28 if(step == 10) {
29 check();
30 return;
31 }
32 for(int i=1;i<10;i++) {
33 if(vis[i]==0) {
34 vis[i] = 1;
35 num [step] = i;
36 dfs(step+1);
37 vis[i] = 0;
38 }
39 }
40 }
41 public static void main(String[] args) {
42 Scanner cin = new Scanner(System.in);
43 n = cin.nextInt();
44 dfs(1);
45 System.out.println(ans);
46 }
47 }