首页 > 其他分享 >1811E Living Sequence 两种解法

1811E Living Sequence 两种解法

时间:2023-04-13 21:24:19浏览次数:49  
标签:Living 1811E Sequence int ll nums mid while include

思维 进制转换 数位DP 无前导0 T3
Problem - 1811E - Codeforces

题目大意

从一个不含有数字4的递增序列中找第k个数并输出。
如 \(1,2,3,5,6,7,8,9,10,11,12\), \(k = 4\) 时输出 \(5\)。

思路1

有一个巧妙的解法:
考虑这个问题, 从一个没有限制的从1开始的递增序列找出第k个数, 显然就是十进制的k。而这里则可以定义新的进制为 "012356789" 9进制, 那么k对应的就是这个特殊的九进制数, 我们只需要把它转换为十进制就行。

二转十:

while(k)
	ans += k % 2, k /= 2;

九转十:

while(k)
	ans += k % 9, k /= 9;

代码1

#include <iostream>
#include <cstring>
#include <vector>
using namespace std;
using LL = long long;
int a[20];
int cnt = 0;

int main()
{

    cin.tie(0);
    cout.tie(0);
    ios::sync_with_stdio(0);
    string s = "012356789";
    int T;
    cin >> T;
    while (T--)
    {

        LL k;
        cin >> k;
        cnt = 0;
        while (k)
            a[cnt++] = s[k % 9] - '0', k /= 9;
        for (int i = cnt - 1; i >= 0; i--)
            cout << a[i];
        cout << endl;
    }
}

思路2

也可以考虑数位DP, 定义 \(f(i,j)\) 为长度为i, 且最高位为j的数, 可以写出这样的初始化函数来得到 \([1,i]\) 的满足条件的数的个数:

void init()
{
    for (int i = 0; i <= 9; i++)
        if (i != 4)
            f[1][i] = 1;
    for (int i = 2; i <= N - 1; i++)
    {
        for (int j = 0; j <= 9; j++)
        {
            if (j == 4)
                continue;
            for (int k = 0; k <= 9; k++)
                f[i][j] += f[i - 1][k];
        }
    }
}

然后再实现查找前缀和 \([1,num]\) 的满足条件的数的个数, 题目中的 \(k\) 最大为 1e12, 直接二分结果, 找最左边且 \(dp(mid) = k\) 的值就是最终结果。

记得要处理前导0, 方法是在首尾不加上0开头的部分, 最后再加一遍所有长度小于 num.size() 的部分。

代码2

#include <iostream>
#include <cstring>
#include <algorithm>
#include <string>
#include <cmath>
#include <vector>
using namespace std;
const int N = 17;
typedef long long ll;
const ll INF = 1e17;
ll f[N][10];

void init()
{
    for (int i = 0; i <= 9; i++)
        if (i != 4)
            f[1][i] = 1;
    for (int i = 2; i <= N - 1; i++)
    {
        for (int j = 0; j <= 9; j++)
        {
            if (j == 4)
                continue;
            for (int k = 0; k <= 9; k++)
                f[i][j] += f[i - 1][k];
        }
    }
}

ll dp(ll x)
{
    if (!x)
        return 0;

    vector<int> nums;
    while (x)
        nums.push_back(x % 10), x /= 10;

    ll res = 0;
    for (int i = nums.size() - 1; i >= 0; i--)
    {
        int x = nums[i];
        for (int j = (i == nums.size() - 1); j < x; j++)
            res += f[i + 1][j];
        if (x == 4)
            break;
        if (!i)
            res++;
    }
    for (int i = 1; i <= nums.size() - 1; i++)
        for (int j = 1; j <= 9; j++)
            res += f[i][j];
    return res;
}

int main()
{
    init();

    int T;
    cin >> T;
    while (T--)
    {
        ll k;
        cin >> k;
        ll l = -1, r = 1e13;
        while (l != r - 1)
        {
            ll mid = l + r >> 1;
            if (dp(mid) < k)
                l = mid;
            else
                r = mid;
        }
        cout << r << endl;
    }
    return 0;
}

标签:Living,1811E,Sequence,int,ll,nums,mid,while,include
From: https://www.cnblogs.com/edwinaze/p/17316429.html

相关文章

  • C. Sequence Master
    题目链接挺有意思的一道题题意:给定一个\(2*n\)长度的数组\(p\),要求构造一个长度也为\(2*n\)的整数数组\(q\),使得\(q\)满足从\(q\)中任选\(n\)个数字的积等于\(q\)中剩下\(n\)个数的和,求出\(p\)与\(q\)的最短距离最短距离定义为对应元素差的绝对值之和由于\(q\)的要求有点严苛......
  • UVa 10049 Self-describing Sequence (自描述序列&二分递推)
    10049-Self-describingSequenceTimelimit:3.000secondshttp://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=34&page=show_problem&problem=990SolomonGolomb's self­describingsequence  istheonlynon­decreas......
  • (KMP 1.1)hdu 1711 Number Sequence(KMP的简单应用——求pattern在text中第一次出现的
    题目:NumberSequenceTimeLimit:10000/5000MS(Java/Others)    MemoryLimit:32768/32768K(Java/Others)TotalSubmission(s):12902    AcceptedSubmission(s):5845ProblemDescriptionGiventwosequencesofnumbers:a[1],a[2],......,a[N],andb[1......
  • UML建模之时序图(Sequence Diagram)
     一、时序图简介(Briefintroduction) 二、时序图元素(SequenceDiagramElements)  角色(Actor)  对象(Object)  生命线(Lifeline)  控制焦点(FocusofControl)  消息(Message)  自关联消息(Self-Message)  CombinedFragments  三、时序图实例分析(SequeceDiagramExampleA......
  • ZOJ - 2421 Recaman's Sequence(打表水题)
    题目大意:A0=0Am=A(m-1)-m,如果Am小于0或者Am前面已经出现过了,那么Am=A(m-1)+m解题思路:打表水题我用的是map,纪录数是否出现过了#include<cstdio>#include<cstring>#include<map>usingnamespacestd;constintN=500010;typedeflonglongLL;map<LL,int>Ma......
  • UVA - 10706 Number Sequence 子序列
    #include<cstdio>#include<cmath>#include<algorithm>usingnamespacestd;constintmaxn=32761;longlongS[maxn];//存放的是S1,S2,到SK的和,S[5]表示了S1到S4的和,当数字变化到K的时候,一共有多少个字数了intborder[9]={0,1,10,100,1000,10000,100000,1000000,10000000......
  • Living Social联手Clear Channel,团购模式渗入电台
    当地时间10月18日,美国最大的广播电台ClearChannel和第二大团购网站LivingSocial宣布联手,今后LivingSocial将作为ClearChannel在90多个城市500多个电台的独家团购供应商。这标志着ClearChannel的业务范围已从在线和移动平台扩张到了为听众提供全方位的生活服务。自宣布合作开......
  • 解决tabix建索引报错[E::hts_idx_push] Unsorted positions on sequence #
    当我对两个基因型文件位置取交集,并重新生成两个vcf:$bcftoolsview-Roverlap.lstvariant.filter.vcf.gz-Oz-o300.vcf.gz出现如下错误:$tabix300.vcf.gz[E::hts_idx_push]Unsortedpositionsonsequence#4:29013869followedby29013853tbx_index_buildfailed:300.......
  • CF1770F Koxia and Sequence
    CF1770FKoxiaandSequence题目链接。\(\text{difficulty}={\color{red}6},1\)。\(\text{tags}=组合数学,子集反演,容斥原理,二进制\)。神仙题。首先进行观察。由于......
  • CF743B Chloe and the sequence 题解 分治
    题目链接:http://codeforces.com/problemset/problem/743/B题目大意:对于一个n-序列,如果n==0,那么它是一个空的序列(也就是说空序列中没有元素)。然后会进行i次操作,每次......