bzoj 4667: 小y的密码

4 篇文章 0 订阅
3 篇文章 0 订阅

不错的题啊 然而我太菜了orz

想一想 不难发现其实从小到大搜索哪几个数并不会超时
然后就算一下就好了。。。

至于怎么算
就枚举哪个位开始低于n的对应位 剩下的位随便填就用组合数算
如果位数比n少直接算就好了 首位不为0即可

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
inline int read(){
    char ch=getchar(); int x=0,f=1;
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}
    while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0'; ch=getchar();}
    return x*f;
}
int n,k,m,a[11],al,ans,c[11],tot,jc[11];
LL d[11];
bool check(){
    if(!tot || !c[tot])return 0;
    LL s=0; int u=c[(tot+1)>>1];
    for(int i=1;i<=tot;++i)
    {
        int g=c[i]-u; LL o= g>=0?d[g]:d[-g];
        if(g<0) s+= k&1?-o:o;
        else s+=o;
    }
    if(s>m)return 0;
    return 1;
}
int num[11];
void add(int x){
    LL s=jc[x];
    for(int i=0;i<=9;++i)s/=jc[num[i]];
    ans+=s;
}
void cal(){
    for(int i=0;i<=9;++i) num[i]=0;
    for(int i=1;i<=tot;++i) num[c[i]]++;
    if(tot<al){
        for(int j=9;j>0;--j)
            if(num[j]>0){
                num[j]--;
                add(tot-1);
                num[j]++;
            }
        return;
    }
    for(int i=tot;i>=1;--i){
        int o= i==tot?0:-1;
        for(int j=a[i]-1;j>o;--j)
            if(num[j]>0){
                num[j]--;
                add(i-1);
                num[j]++;
            }
        if(!num[a[i]])break;
        num[a[i]]--; if(i==1)ans++;
    }
}
void dfs(int x){
    if(check())cal();
    if(tot==al)return;
    ++tot;
    for(int i=x;i<=9;++i)
        c[tot]=i,dfs(i);
    --tot;
}
int main()
{
    n=read(),k=read(),m=read();
    while(n) a[++al]=n%10,n/=10;
    jc[0]=1; for(int i=1;i<=al;++i)jc[i]=jc[i-1]*i;
    for(int i=0;i<=9;++i){
        d[i]=1;
        for(int j=1;j<=k;++j)d[i]*=i;
    }
    dfs(0);
    printf("%d\n",ans);
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值