Codeforces Round 863 (Div. 3) ABCE题解

文章展示了几个编程问题的解决方案,包括贪心算法处理数字序列,简单的数学计算确定点的位置层级,直观的数学构造解决数组问题,以及结合数位动态规划和二分查找找特定数字范围内的特定条件数。

A:

贪心:

void solve()

{

    int n,m;

    cin>>n>>m;

    for(int i=1;i<=n;i++)

        cin>>a[i];

    bool prime=false;

    for(int i=1;i<=n;i++)

    {

        if(a[i]-'0'>=m||prime)

            cout<<a[i];

        else

        {

            cout<<m<<a[i];

            prime=true;

        }

    }

    if(prime==false)

        cout<<m;

    cout<<endl;

}

B:

主要是读题困难,

简单数学定量计算

//计算一个点处于第几层

int f(int x,int y)

{

    x=min(x,1+n-x);

    y=min(y,1+n-y);

    if(x<y)

        swap(x,y);

    int res=n/2+1-y;

    return res;

}

void solve()

{

    cin>>n>>x1>>y1>>x2>>y2;

    cout<<abs(f(x1,y1)-f(x2,y2) )<<endl;

}

C:

构造;(基于直觉的数学构造

int a[N],b[N];

void solve()

{

    int n;

    cin>>n;

    for(int i=1;i<n;i++)

        cin>>b[i];

    b[0]=b[1];

    for(int i=1;i<=n;i++)

    {

        a[i]=min(b[i-1],b[i]);

        if(b[i-1]!=a[i-1]&&b[i-1]!=a[i])

            a[i]=b[i-1];

    }

    for(int i=1;i<=n;i++)

        cout<<a[i]<<" \n"[i==n];

}

D:

待补

E:

数位dp板子+二分

const int N=15;

ll f[N][N];        //f[i][j] 表示 我们填到第i位,当第i位填j的时候有多少种合适的数字

void init()

{

    for(int i=0;i<=9;i++)

        f[1][i]=1;          //初始化

    f[1][4]=0;              //第i位置填写

    for(int i=2;i<=14;i++)

        for(int j=0;j<=9;j++)

            for(int k=0;k<=9;k++)

            {

                if(k==4||j==4)

                    continue;

                f[i][j]+=f[i-1][k];

            }

}

ll dp(ll x)       //0-x范围内有多少个满足条件的数

{

    if(!x)  return 0;

    ll a[15]={0};

    ll l=0;

    ll ans=0;

    ll las=0;

    while(x)

    {

        a[++l]=x%10;

        x/=10;

    }

    for(int i=l;i>=1;i--)

    {

        for(int j=0;j<a[i];j++)

        {

            if(j==4)    continue;

            ans+=f[i][j];

        }

        if(a[i]==4)

            break;

        las=a[i];

        if(i==1)

            ans++;

    }

    return ans-1;

}

bool check(ll x,ll k)

{

    if(dp(x)>=k)

        return true;

    return false;

}

void solve()

{

    ll k;

    cin>>k;

    ll l=1,r=1e14;

    //二分查找第一个为k的值

    ll ans=l;

    while(l<=r)

    {

        ll mid=l+r>>1;

        if(check(mid,k))

        {

            ans=mid;

            r=mid-1;

        }

        else

        {

            ans=mid+1;

            l=mid+1;

        }

    }

    cout<<ans<<endl;

}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值