• bzoj1072: [SCOI2007]排列perm


    1072: [SCOI2007]排列perm

    Time Limit: 10 Sec  Memory Limit: 128 MB

    Description

      给一个数字串s和正整数d, 统计s有多少种不同的排列能被d整除(可以有前导0)。例如123434有90种排列能
    被2整除,其中末位为2的有30种,末位为4的有60种。

    Input

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

    Output

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

    Sample Input

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

    Sample Output

    1
    3
    3628800
    90
    3
    6
    1398

    HINT

    在前三个例子中,排列分别有1, 3, 3628800种,它们都是1的倍数。

    【限制】

    100%的数据满足:s的长度不超过10, 1<=d<=1000, 1<=T<=15

    Source

    暴力DFS:

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 #include<algorithm>
     5 using namespace std;
     6  
     7 int n,m,t,len,res,num[11],a[11],d;
     8 char s[20];
     9  
    10 bool check(){
    11     long long o=0;
    12     for(int i=len;i>0;i--)
    13         o=o*10+a[i];
    14     if(o%d==0) return 1;
    15     else return 0;
    16 }
    17  
    18 int dfs(int x){
    19     int ans=0;
    20     if(x==len+1){
    21         if(check())
    22             return 1;
    23         else return 0;
    24     }
    25     for(int i=0;i<10;i++)
    26     if(num[i]>0){
    27         a[x]=i;
    28         num[i]--;
    29         ans+=dfs(x+1);
    30         num[i]++;
    31     }
    32     return ans;
    33 }
    34  
    35 int main(){
    36     scanf("%d",&t);
    37     for(int ii=1;ii<=t;ii++){
    38         res=0;
    39         scanf("%s %d",s,&d);
    40         len=strlen(s);
    41         memset(num,0,sizeof(num));
    42         for(int i=0;i<len;i++)
    43             num[s[i]-'0']++;
    44         res=dfs(1);
    45         printf("%d
    ",res);
    46     }
    47 }

    状压DP:

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 #include<algorithm>
     5 using namespace std;
     6  
     7 int len,n,m,t,dp[1025][1008],tot[11],v[11],d,ex[11];
     8 char s[108];
     9  
    10 void solve(){
    11     memset(dp,0,sizeof(dp));
    12     dp[0][0]=1;
    13     for(int i=0;i<ex[len];i++)
    14         for(int j=0;j<d;j++)
    15             if(dp[i][j]){
    16                 for(int k=0;k<len;k++)
    17                     if((i&ex[k])==0)
    18                         dp[i|ex[k]][(j*10+s[k]-'0')%d]+=dp[i][j];
    19             }
    20 }
    21  
    22 int main(){
    23     scanf("%d",&t);
    24     ex[0]=1;
    25     for(int i=1;i<=10;i++) ex[i]=ex[i-1]*2;
    26     while(t--){
    27         scanf("%s %d",s,&d);
    28         len=strlen(s);
    29         for(int i=0;i<=10;i++) v[i]=1,tot[i]=0;
    30         for(int i=0;i<len;i++){
    31             int x=s[i]-'0';
    32             tot[x]++;
    33             v[x]*=tot[x];
    34         }
    35         solve();
    36         for(int i=0;i<=9;i++) dp[ex[len]-1][0]/=v[i];
    37         printf("%d
    ",dp[ex[len]-1][0]);
    38     }
    39 }
  • 相关阅读:
    关于负数补码的求解
    二维数组的行列指针
    复杂类型的解读
    单斜杠''的思考
    HTML 文本格式化实例--常用的标签
    P1 基础知识以及客户截面 【B站 SolidWorks2014教学视频 共计20讲】
    SolidWorks 2-5 草图的绘制
    SolidWorks 2-4 草图简介
    SolidWorks 模型创建的一般过程 2019年2月25日
    P3 3.HTML&CSS基础_HTML简介 (24'22")---------- 高质量HTML与CSS基础(共103讲)
  • 原文地址:https://www.cnblogs.com/WQHui/p/8575567.html
Copyright © 2020-2023  润新知