1 条题解

  • -1
    @ 2022-6-5 10:14:20

    luogu

    #include<bits/stdc++.h>
    using namespace std;
    long long val_fac[20],val_pow[10];
    long long step_1[20];
    void decontor(int n,int p)//逆康托展开
    {
    	vector<int>mus,ans;
    	int now=p-1,i;
    	for(i=1;i<=n;i++)
    		mus.push_back(i);
    	for(i=n;i>=1;i--)
    	{
    		int l=now/val_fac[i-1];
    		now=now%val_fac[i-1];
    		ans.push_back(mus[l]);
    		mus.erase(mus.begin()+l);
    	}
    	for(i=0;i<n;i++)
    		step_1[i+1]=ans[i];
    }
    int Digit(int num)//找位数
    {
    	int sum=0;
    	while(num)
    	{
    		num/=10;
    		sum++;
    	}
    	return sum;
    }
    void change(long long &n)//改成下一个幸运数
    {
    	long long ans=n;
    	int sum=0;
    	while(ans%10==7)//即上文说的找法
    	{
    		ans/=10;
    		n-=3*(int)pow(10,sum);
    		sum++;
    	}
    	n+=3*(int)pow(10,sum);
    }
    bool check(int val)//检查是否满足幸运数的条件
    {
    	while(val)
    	{
    		if(val%10!=4&&val%10!=7)
    			return 0;
    		val/=10;
    	}
    	return 1;
    }
    int main()
    {
    	int p,i,n;
    	long long ans=0;
    	scanf("%d %d",&n,&p);
    	val_fac[0]=1;
    	val_pow[0]=1;
    	for(i=1;i<=15;i++)//逆康托展开前置
    		val_fac[i]=val_fac[i-1]*i;
    	int dig=Digit(n);//求位数
    	for(i=1;i<=dig;i++)//预处理
    		val_pow[i]=val_pow[i-1]*2;
    	if(p>val_fac[min(n,13)])//判断-1
    	{
    		printf("-1");
    		return 0;
    	}
    	decontor(min(n,13)/*最多13位,否则就不行了*/,p);
    	if(n>13)
    	{
    		if(n>19)//不会影响到任何低于dig位的幸运数
    			for(i=1;i<dig;i++)
    				ans+=val_pow[i];
    		if(n>16&&n<20)//会影响到7
    			ans++;
    		for(i=1;i<=13;i++)//在逆康托展开中使用的是1~13,需要加回来
    			step_1[i]=step_1[i]+n-13;
    		long long now=0,biggest=0;
    		for(i=1;i<=dig;i++)//找到dig位的幸运数的最小值和最大值
    			now*=10,now+=4,biggest*=10,biggest+=7;
    		if(n-13>=biggest)//不会影响到dig位的所有幸运数
    			ans+=val_pow[dig],now=n-12/*防止进入循环*/;
    		while(now<=n-13&&now!=biggest)
    		{
    			ans++;
    			change(now);
    		}
    		if(now<=n-13&&now==biggest)
    			ans++;
    		for(i=1;i<=13;i++)//暴力查找
    		{
    			if(check(n+i-13)&&check(step_1[i]))
    				ans++;
    		}
    	}
    	else
    	{
    		if(step_1[4]==4||step_1[4]==7)
    			ans++;
    		if(step_1[7]==4||step_1[7]==7)
    			ans++;
    	}
    	printf("%lld",ans);
    	return 0;
    }
    
    • @ 2022-6-29 13:05:29

      循环的i都没定义

  • 1

信息

ID
384
时间
1000ms
内存
125MiB
难度
4
标签
递交数
2
已通过
2
上传者