美文网首页DataStructure
Codeforce101061E-Playing with nu

Codeforce101061E-Playing with nu

作者: 雨落八千里 | 来源:发表于2019-07-25 13:40 被阅读0次
  • Playing with numbers
  • 题意:
  • 给你两个数字s和n,在不改变s的数字顺序下,删除n个数使剩下来的数最大或最小。(包含前导零)。并且n不会大于s的长度。
  • 思路:
  • 给出数字s就一定知道数字s的长度lenlen个数字删除n个数字,那么剩下X=len-n个数字。要使得这X个数字组成的数W最小。所以最高位首先应该最小。那首位的范围在哪呢?假如在全部的数字(1~len)中查找,那假如最后一个数字最小,组合的数字W的第二位肯定在第一位后面,那就不可行了,就找不到X个数字了。所以极端的思想就是找到len个数字最后的X个数字组合的数就是我们要求的最大数或最小数。那么第一个数字一定在(1~n+1)中出现。
  • 我们可以这样来模拟一下:假设A数组就只有6个数,分别是A[1],A[2],A[3],A[4],A[5],A[6],我们去掉 n=2个数,使形成的值最小。
    那么我们此时的len=6,n=2X=len-n=4
    则我们说形成的4位数的第一位一定在区间[1,3]中出现,因为如果区间范围再大点,比如[1,4],这样就不科学了,因为第一位一定不会是A[4],更不会是
    A[5],A[6],我们假设可以是A[4],那么后面只有A[5],A[6]两位数了,这样的话最多只可能形成3位数,绝对不能形成len-n=4位了。
    当然到了这里,我们就可以这样做了,第一位可以在区间[1,n+1]里面找,假设第一位在位置tem因为第二位肯定在第一位的后面,所以第二位一定存在于
    区间[tem+1,n+2],为什么是n+2,因为第一位已经确定了,现在只需要确定len-n-1位了,第二次继续采用极端的思想,len最后的几位符合情况,那么说明第二次的第一个数是n+2,搜索区间是[tem+1,n+2],所以区间就可以向后增加1,一直这样循环下去,就可以找到留下来的最大值或最小值。
#include<bits/stdc++.h>
using namespace std;
queue<char>qu1,qu2;
char s[100010];
int dpmaix[100010][24];//存放的是第i个字符开始,连续的2^j个字符的最大字符的下标
int dpminx[100010][24];//存放的是第i个字符开始,连续的2^j个字符的最小字符的下标
int n;
int findmaix(int x,int y)//返回较大字符的下标
{
    if(s[x]>=s[y])
    {
        return x;
    }
    else
    {
        return y;
    }
    
}
int findminx(int x,int y)//返回较小字符的下标
{
    if(s[x]<=s[y])
    {
        return x;
    }
    return y;
}
void ST(int n)
{
    for(int i=0;i<n;i++)
    {
        dpmaix[i][0]=dpminx[i][0]=i;//初始化(从第i个连续的1个字符中自身最大或最小)
    }
    for(int j=1;j<=25;j++)
    {
        for(int i=0;i+(1<<j)-1<n;i++)
        {
            dpmaix[i][j]=findmaix(dpmaix[i][j-1],dpmaix[i+(1<<(j-1))][j-1]);//寻找从第i个字符连续的2^j个字符中最大的字符下标
            dpminx[i][j]=findminx(dpminx[i][j-1],dpminx[i+(1<<(j-1))][j-1]);//寻找从第i个字符连续的2^j个字符中最小的字符下标
        }
    }
}
int querymaix(int i,int j)
{
    int k=log2(j-i+1.0);
    return findmaix(dpmaix[i][k],dpmaix[j-(1<<k)+1][k]);//返回区间的最大字符的下标
}
int queryminx(int i,int j)
{
    int k=log2(j-i+1.0);
    return findminx(dpminx[i][k],dpminx[j-(1<<k)+1][k]);//返回区间的最小字符的下标
}
int main( )
{
    int t;
    cin>>t;
    getchar( );
    while(t--)
    {
        while(!qu1.empty( ))
        {
            qu1.pop( );
        }
        while(!qu2.empty( ))
        {
            qu2.pop( );
        }
        scanf("%s %d",s,&n);
        //cout<<s<<endl;
        int len=strlen(s);
        ST(len);
        int x=len-n;
        int temaix=0,tep=n,teminx=0;
        for(int i=1;i<=x;i++)
        {
            temaix=querymaix(temaix,tep);
            teminx=queryminx(teminx,tep);
            tep++;//区间n往后移动
            qu1.push(s[temaix]);
            qu2.push(s[teminx]);
            temaix++;
            teminx++;
        }
        while(!qu2.empty( ))
        {
            cout<<qu2.front( );
            qu2.pop( );
        }
        cout<<endl;
        while(!qu1.empty( ))
        {
            cout<<qu1.front( );
            qu1.pop( );
        }
        cout<<endl;
    }
    return 0;
}

相关文章

  • Codeforce101061E-Playing with nu

    Playing with numbers题意:给你两个数字s和n,在不改变s的数字顺序下,删除n个数使剩下来的数最...

  • 无标题文章

    8866@66666.nu【8866@66666.nu】8866@66666.nu

  • MAC Shell命令随记

    平时使用不多,用到哪记到哪(捂脸.gif) VIM 设置行号set nu按行号删除nu1,nu2d删除nu1到nu...

  • 陈秋婵总结太婆分享

    四大主题 Nu生活:读书,做点心,美食会 nu美丽:化妆,服装搭配, Nu健康:健身,营养学 轻食派对 Nu缤纷:...

  • Nu编程

    原文见About Nu(TM) Nu简介 编写一个软件非常简单,但是写一个好的软件却很难,特别是当项目变得越来越大...

  • NU TOWN

    时间️:2019年5月12日 坐标:守一堂 读书会发起人:杨颜鸿 积极行动的阅读者:8人 “如果你喜欢和人交往,而...

  • NU TOWN

    时间️:2019年5月12日 坐标:守一堂 读书会发起人:杨颜鸿 积极行动的阅读者:8人 “如果你喜欢和人交往,而...

  • 2018-08-03

    m nu

  • CTFer成长之路-Web入门之信息收集

    Nu1L战队官网:https://nu1l.com[https://nu1l.com]“空指针”高质量挑战赛:ht...

  • BP神经网络matlab代码

    clear clc alpha=0.05; eta=0.2; ny=2;d=2;nu=3; n=ny+nu-d+1...

网友评论

    本文标题:Codeforce101061E-Playing with nu

    本文链接:https://www.haomeiwen.com/subject/urzcrctx.html