列表

详情


NC19979. [HAOI2010]计数

描述

你有一组非零数字(不一定唯一),你可以在其中插入任意个0,这样就可以产生无限个数。比如说给定{1,2},那么可以生成数字12,21,102,120,201,210,1002,1020,等等。 现在给定一个数,问在这个数之前有多少个数。(注意这个数不会有前导0).  

输入描述

只有1行,为1个整数n.

输出描述

只有整数,表示N之前出现的数的个数。

示例1

输入:

1020

输出:

7

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 16ms, 内存消耗: 8300K, 提交时间: 2019-04-12 11:35:50

#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,ans,a[55],v[105],c[1005][1005];
int suan()
{
    int ans=1;
    int m=n;
    for(int i=0;i<=9;i++)
		if(a[i])
		{
			ans*=c[m][a[i]];
			m-=a[i];
		}
    return ans;
}
signed main()
{
	for(int i=0;i<=1000;i++)c[i][0]=1;
	for(int i=1;i<=1000;i++)
		for(int j=1;j<=1000;j++)c[i][j]=c[i-1][j]+c[i-1][j-1];
	char c;
	c=getchar();
	while(!isdigit(c))c=getchar();
	while(isdigit(c))
	{
		v[++n]=c-48;
		a[v[n]]++;
		c=getchar();
	}
    int nn=n;
    for(int i=1;i<=nn;i++)
	{
        n--;
        for(int j=0;j<v[i];j++)
        	if(a[j])
			{
				a[j]--;
				ans+=suan();
				a[j]++;
			}
        a[v[i]]--;
    }
    printf("%lld",ans);
}

C++11(clang++ 3.9) 解法, 执行用时: 3ms, 内存消耗: 504K, 提交时间: 2020-09-07 17:13:57

#include<bits/stdc++.h>
#define LL long long
using namespace std;
int n,cnt[55];LL c[55][55],ans;char str[55];
int main(){
	scanf("%s",str+1);n=strlen(str+1);
	for(int i=1;i<=n;i++)cnt[str[i]-'0']++;
	for(int i=0;i<=n;i++)c[i][0]=1;
	for(int i=1;i<=n;i++)for(int j=1;j<=i;j++)c[i][j]=c[i-1][j-1]+c[i-1][j];
	for(int i=1;i<=n;i++){
		for(int j=0,t;j<str[i]-'0';j++)if(cnt[j]){
			cnt[j]--;t=n-i;LL res=1;
			for(int k=0;k<=9;k++)res=res*c[t][cnt[k]],t-=cnt[k];
			ans+=res;cnt[j]++;
		}
		cnt[str[i]-'0']--;
	}
	printf("%lld\n",ans);
	return 0;
}

上一题