zoukankan      html  css  js  c++  java
  • 排列(STL函数运用/状压dp)

    题目描述

    给一个数字串s和正整数d , 统计s有多少种不同的排列能被d整除(可以有前导0)。

    例如123434有90种排列能被2整除,其中末位为2 的有 30 种,末位为4 的有60种。

    输入格式

    输入第一行是一个整数T,表示测试数据的个数,以下每行一组 s 和 d ,中间用空格隔开。s 保证只包含数字0,1,2,3,4,5,6,7,8,9.

    输出格式

    每个数据仅一行,表示能被d整除的排列的个数。

    样例

    样例输入

    7
    000 1
    001 1
    1234567890 1
    123434 2
    1234 7
    12345 17
    12345678 29
    

    样例输出

    1
    3
    3628800
    90
    3
    6
    1398
    

    s的长度不超过10,1<=d<=1000,1<=T<=15;

     方法一:状压dp状态转移

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn=1<<10;
    int d,len,dp[maxn<<1][maxn],c[maxn],a[maxn];
    char s[15];
    int main() {
        int t;
        scanf("%d",&t);
        while(t--) {
            memset(dp,0,sizeof(dp));
            scanf("%s",s);
            len=strlen(s);
            scanf("%d",&d);
            for(int i=0;i<len;i++) a[i+1]=s[i]-'0';
            int Maxn=(1<<len)-1;
            dp[0][0]=1;
            for(int s=0;s<=Maxn;s++) {
                memset(c,0,sizeof(c));
                for(int i=1;i<=len;i++) {
                    if(!(s&(1<<(i-1)))&&!c[a[i]]) {
                        c[a[i]]=1;
                        for(int j=0;j<d;j++) {
                            dp[s|(1<<(i-1))][(j*10+a[i])%d]+=dp[s][j];//dp[s][j](s为选的数字状态的压缩,选的几个数字取模后余j)的方案数
                        }
                    }
                }
            }
            printf("%d
    ",dp[Maxn][0]);
        }
        return 0;
    }

    方法二:STL全排列函数

    用STL库中的全排列函数的解法(自带判重加修改)

    next_permutation从递增数列求出全排列组合(从小到大);

    相反函数:prev_permutation(从大到小)

    全排列讲解:https://blog.csdn.net/qq_26849233/article/details/73951266

    然后运用函数暴力枚举全排列,计算个数;

    #include <bits/stdc++.h>
    using namespace std;
    inline int read(){
        int x = 0, w = 1;
        char ch = getchar();
        for(; ch > '9' || ch < '0'; ch = getchar()) if(ch == '-') w = -1;
        for(; ch >= '0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0';
        return x * w;
    }
    
    const int maxn = 5200;
    char ch[maxn];
    int a[maxn];
    
    signed main(){
        int t = read();
        int ans = 0;
        while(t--){
            cin >> ch;
            int n = read();
            int len = strlen(ch);
            for(int i = 0; i < len; i++){
                a[i + 1] = ch[i] - '0';
            }
            sort(a + 1, a + 1 + len);
            ans = 0;
            do{
                int tmp = 0;
                for(int i = 1 ;i <= len; i++)
                    tmp = tmp * 10 + a[i];
                if(tmp % n == 0) ans++;
            }while(next_permutation(a + 1, a + 1 + len));
            cout << ans << endl;
        }
        return 0;
    }

     午歌:apologize

  • 相关阅读:
    线程的等待与唤醒
    多线程start()与run()的区别
    Thread与Runnable
    关于i++和++i的一些见解
    Mysql优化(转)
    Java 注解
    Java 泛型(转)
    Java 中的CAS
    CAS ABA问题
    Java 线程池分析
  • 原文地址:https://www.cnblogs.com/1999-09-21Karry-erfs/p/13197731.html
Copyright © 2011-2022 走看看