蓝桥杯:带分数——全排列+回溯

带分数

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

题解:

我们先将1-9进行全排列,这里由于java没有内置的全排列函数所以需要自己来实现;

  • 接着去找加和除的位置,加号前的数最长也只能是7位数,而且因为后面的除法运算不能为0,所以除数最长只能在倒数第二个数就停止截取。
  • 接着去判断除数是否能整除,因为我们和为整数,左边加的也是整数,所以假分数也一定要为整数,且此表达式要最终返回n。

代码:

import java.util.Scanner;
 
 
public class Main {
 
    static int []arr={1,2,3,4,5,6,7,8,9};
    static int n;
    static int count=0;
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Scanner scanner=new Scanner(System.in);
        n=scanner.nextInt();
        qpl(0);
        System.out.println(count);
 
    }
     
    //全排列
    public static void qpl(int n) {
        if (n==9) {
            scc(arr);
        }
        for (int i = n; i < 9; i++) {
            int zjs=arr[i];
            arr[i]=arr[n];
            arr[n]=zjs;
             
            qpl(n+1);
             
            //回溯
            zjs=arr[i];
            arr[i]=arr[n];
            arr[n]=zjs;
        }
    }
     
    public static void scc(int []arr) {
        for (int i = 1; i <= 7; i++) {
                int jhq=jq(0, i);//+前的数
                if (jhq>=n) {
                    continue;
                }
            for (int j = 1; j < 9-i; j++) {
                int num1=jq(i, j);
                int num2=jq(i+j, 9-i-j);
                if (num1%num2==0&&jhq+num1/num2==n) {
                    count++;
                }
            }
        }
    }
     
    public static int jq(int qd,int cd) {
        int nn=1;
        int num=0;
        for (int i =qd+cd-1; i >=qd; i--) {
            num+=arr[i]*nn;
            nn*=10;
        }
        return num;
    }
 
}

你可能感兴趣的:(蓝桥杯,#,DFS与递归及回溯,蓝桥杯,全排列,回溯)