2 条题解

  • 1
    @ 2023-12-11 16:37:33

    算法 1

    递归常数太大了,这里采用STL函数 next_permatation.

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    const int N=11;
    char str[N];
    int d,a[N];
    int main(){
    	int t;scanf("%d",&t);
    	while(t--){
    		scanf("%s%d",str+1,&d);
    		int n=strlen(str+1),ans=0;
    		for(int i=1;i<=n;i++){
    			a[i]=str[i]-'0';
    		}
    		sort(a+1,a+n+1);
    		do{
    			LL res=0;
    			for(int i=1;i<=n;i++){
    				res=(res<<1)+(res<<3)+a[i];
    			}
    			if(res%d==0)ans++;
    		}while(next_permutation(a+1,a+n+1));
    		printf("%d\n",ans);
    	}
    	return 0;
    }
    

    算法 2

    #include<bits/stdc++.h>
    using namespace std;
    const int N=11,M=(1<<11);
    char str[N];
    int d,a[N],cnt[N],f[M][M],fac[N];
    void init(){
    	fac[0]=1;
    	for(int i=1;i<=10;i++){
    		fac[i]=fac[i-1]*i;
    	}
    }
    int main(){
    	init();
    	int t;scanf("%d",&t);
    	while(t--){
    		scanf("%s%d",str,&d);
    		int n=strlen(str);
    		memset(cnt,0,sizeof(cnt));
    		for(int i=0;i<n;i++){
    			a[i]=str[i]-'0';
    			cnt[a[i]]++;
    		}
    		memset(f,0,sizeof(f));
    		f[0][0]=1;
    		for(int i=0;i<(1<<n);i++){
    			for(int j=0;j<d;j++){
    				for(int k=0;k<n;k++){
    					if(!(i&(1<<k))){
    						f[i|(1<<k)][(j*10+a[k])%d]+=f[i][j];
    					}
    				}
    			}
    		}
    		int ans=f[(1<<n)-1][0];
    		for(int i=0;i<=9;i++){
    			if(cnt[i]>1){
    				ans=ans/fac[cnt[i]];
    			}
    		}
    		printf("%d\n",ans);
    	}
    	return 0;
    }
    
    • 1
      @ 2022-9-5 22:36:19
      #include<iostream>
      #include<cstdio>
      #include<cstring>
      #include<cmath>
      
      using namespace std;
      const int MAXN = 11;
      
      int T,d,a[MAXN],cnt,dp[1<<MAXN][1002];
      bool b[MAXN];
      char s[MAXN];
      
      int main(){
      	scanf("%d",&T);int len;
      	while(T--){
      		memset(dp,0,sizeof(dp));
      		scanf("%s%d",s+1,&d);
      		len=strlen(s+1);cnt=0;
      		for(register int i=1;i<=len;i++) a[i]=s[i]-'0';//把所有数字存一下
      		dp[0][0]=1;  //赋初值
      		for(register int S=0;S<(1<<len)-1;S++){ //S表示当前所选的状态集合
      			memset(b,0,sizeof(b));  //注意清零
      			for(register int j=1;j<=len;j++)if(!(S&(1<<(j-1))) && !b[a[j]]){ //如果a[j]已经转移过就不能继续转移了,j表示遍历s中的各位数字。
      				b[a[j]]=1;
      				for(register int k=0;k<d;k++) //k表示对d取余后的数
      					dp[S|(1<<(j-1))][(k*10+a[j])%d]+=dp[S][k];
      			}
      		}
      		printf("%d\n",dp[(1<<len)-1][0]);
      	}
      	return 0;
      }
      
      • 1

      信息

      ID
      1072
      时间
      1000ms
      内存
      256MiB
      难度
      9
      标签
      (无)
      递交数
      9
      已通过
      7
      上传者