首页 > 试题广场 >

数字的重排列

[编程题]数字的重排列
  • 热度指数:439 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解

给一个数不包含前导0的数n,现在将n的各位数字的顺序重组,在这些数中,有多少个数是m的倍数?
例如112,重组后有三个数:112,121,211


输入描述:

输入包含两个数,n和m,含义如题面所示



输出描述:

输出一个数,代表m的倍数的个数。

示例1

输入

112 4

输出

1

说明

暴力回溯   超时  这数据太大了



import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;

public class Main{
    static int count = 0;
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String str = sc.nextLine();
        String[] s = str.split(" ");
        char[] ch = s[0].toCharArray();
        Arrays.sort(ch);
        int m = Integer.parseInt(s[1]);
        //int count = 0;
        boolean[] used = new boolean[ch.length];
        ArrayList<Character> path = new ArrayList<>();
        backtracking(ch, used, path, m);
        System.out.println(count);
    }
    public static void backtracking(char[] ch, boolean[] used, ArrayList<Character> path, int m) {
        if(path.size() == ch.length) {
            if(path.get(0) == '0') return;
            StringBuilder bui = new StringBuilder();
            for(Character c : path) {
                bui.append(c);
            }

            int ss = Integer.parseInt(bui.toString());
            if(ss % m == 0) count++;
            //System.out.println(count);
            return;
        }
        for (int i = 0; i < ch.length; i++) {
            if (i > 0 && ch[i] == ch[i - 1] && used[i - 1] == false) {
                continue;
            }
            //如果同⼀树⽀nums[i]没使⽤过开始处理
            if (used[i] == false) {
                used[i] = true;//标记同⼀树⽀nums[i]使⽤过,防止同一树枝重复使用
                path.add(ch[i]);
                backtracking(ch, used, path, m);
                path.remove(path.size() - 1);//回溯,说明同⼀树层nums[i]使⽤过,防止下一树层重复
                used[i] = false;//回溯
            }
        }
    }
}

编辑于 2022-04-10 16:38:44 回复(1)
import java.math.BigInteger;
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        String[] s = in.nextLine().split(" ");
        char[] c = s[0].toCharArray();
        Arrays.sort(c);
        v = new boolean[c.length];
        back(c, Integer.parseInt(s[1]));
        System.out.println(res);
    }
    // 数字重排列-回溯爆搜 ac不了全部
    static boolean[] v;
    static StringBuilder select = new StringBuilder();
    static int res = 0;
    public static void back(char[] c, int m) {
        if (select.length() == c.length) {
            if (select.charAt(0) == '0') return; // 有前导0不要
            BigInteger i = new BigInteger(select.toString());
            if (i.mod(BigInteger.valueOf(m)).equals(BigInteger.ZERO)) {
                res++;
            }
            return;
        }
        for (int i = 0; i < c.length; i++) {
            if (i > 0 && c[i] == c[i-1] && !v[i-1]) continue; // 剪枝
            if (!v[i]) {
                v[i] = true;
                select.append(c[i]);
                back(c, m);
                v[i] = false;
                select.deleteCharAt(select.length()-1);
            }
        }
    }
}
发表于 2022-07-13 17:21:03 回复(0)
/**
* 不知道如何退出 例子只过 5个
**/
import java.util.*;
public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        String n = sc.next();
        int m = sc.nextInt();
        // 对n进行重组 有多少个是m的倍数
        // 对n的每位数放入数组中 0-9 各多少个
        int[] arr = method(n);
        int g = m;
        int count = 0;
        while(true){
            g = g + m;
            int[] arr1 = method2(g);
            // 不知道 如何退出 求指点
            if(g > 1000000){break;}
            boolean flag = true;
            for(int i = 0; i < 10; i++){
                if(arr[i] != arr1[i]){
                    flag = false;
                    break;
                }
            }
            if(flag){
                count++;
            }
        }
        System.out.println(count);
    }
    static int[] method(String n){
        int[] arr = new int[10];
        for(int j = 0; j < n.length(); j++){
            char c = n.charAt(j);
            int i =  c - '0';
            arr[i]++;
        }
        return arr;
    }
    static int[] method2(int n){
        int[] arr = new int[11];
        int len = 0;
        while(n > 0){
            int i = n % 10;
            n = n / 10;
            arr[i]++;
            len++;
        }
        arr[10] = len;
        return arr;
    }
}

发表于 2022-09-12 23:22:37 回复(0)
int main(){
    int n = 112;
    int m = 4;
    string s = to_string(n);
    sort(s.begin(), s.end());
    int cnt = 0;
    do{
        if(stoi(s)%m==0) cnt++;
    }while(next_permutation(s.begin(), s.end()));
    cout << cnt;
}

发表于 2022-08-17 19:51:59 回复(0)