2 条题解
-
1
算法 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
#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
- 上传者