AcWing.排列

文章介绍了一个数学与编程相结合的问题,涉及到字典排序、深度优先搜索(DFS)策略。题目要求在1到10^9的范围内,找出所有只包含4和7的数字,并按字典序排列。给定一个目标位置m,求第m个这样的数字。程序通过计算不同位数的数字数量,使用DFS进行排列组合,并找到目标数字。
摘要由CSDN通过智能技术生成

记录第一次补困难题,竟然思路会一点,虽然我不会代码写出来

 整体思路:首先,如果按字典排序的个数<m,就输出-1;然后dfs排列1-n中只含4和7的数字,1<=n<=1e9,n最多为九位数,

一位数2的1次方

两位数

2的2次方
三位数2的3次方
..........
九位数2的九次方
总共2的10次方-2

然后算出来按字典排序的第k个序列,当g<=n-k时,前g个数字不变换,仍为本身,只需算后n-k+1-n的数字即可,然后看只含4和7的位置的数字也只能含有4和7,符合题意ans++,最后输出ans即可。

#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,m,ans;
bool st[20];
int f(int x)
{
	int s=1;
	for(int i=1;i<=x;i++)
	{
		s*=i;
		if(s>m)
		return m+1;
	}
	return s;
}
int getax(int g)
{
	int k=1;
	while(f(k)<m)
	k++;
	if(g<=n-k)
	return g;
	memset(st,0,sizeof (st));
	int rank=m;
	for(int i=n-k+1;i<=n;i++)
	{
		for(int j=1;j<=k;j++)
		{
			if(!st[j])
			{
				int t=f(n-i);
				if(t<rank)
				rank-=t;
				else
				{
					if(g==i)
					return j+n-k;
					st[j]=true;
					break;
				}
			}
		}
	}
	return -1;
}
//bool only47(int a1)
//{
//    string str=to_string(a1);
//    for(auto c:str)
//    {
//    	if(c!='4'&&c!='7')
//        return false;		
//	}
//    return true;
//}
bool only47(int a1)
{
	string s=to_string(a1);
	for(int i=0;i<s.size();i++)//字符串下标从0开始
	{
		if(s[i]!='4'&&s[i]!='7')
		return false;
	}
	return true;
}
void dfs(int d)
{
	if(d>n)
	return ;
	if(d&&only47(getax(d)))
	ans++;
	dfs(d*10+4);
	dfs(d*10+7);
	
}
signed main()
{
	ios::sync_with_stdio(false); 
	cin.tie(0); 
	cout.tie(0);
	cin>>n>>m;
	if(f(n)<m)
	{
		cout<<"-1";
	}
	else
	{
		dfs(0);
		cout<<ans;
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值