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

  • 相关阅读:
    函数指针
    动态内存
    char*和char[]的区别
    C语言基本数据类型大小
    html5新特性localStorage和sessionStorage
    Swoole实现h5版聊天室笔记
    php使用mysql之sql注入(功)
    Http协议工作特点和工作原理笔记
    原生js使用ajax
    php常用的几个预定义变量
  • 原文地址:https://www.cnblogs.com/1999-09-21Karry-erfs/p/13197731.html
Copyright © 2011-2022 走看看