首页 > 其他分享 >P5513 [CEOI2013] Board CWOI1114C

P5513 [CEOI2013] Board CWOI1114C

时间:2023-11-14 17:22:47浏览次数:31  
标签:int CEOI2013 P5513 ++ len -- Board operator now

70分做法非常容易想到,使用高精度对经过的点编号,令 \(pos\) 为点的编号,初始为 \(1\) ,则:

  • 1 :\(pos<<=1\)
  • 2 :\(pos<<=1|1\)
  • U :\(pos>>=1\)
  • L :\(pos--\)
  • R :\(pos++\)
#include<bits/stdc++.h>
#define int long long
using namespace std;

const int N=1e5+5,inf=1e18;
int ans=inf,dx,dy;
string s;
struct BIG_INT{
    int len;
    short a[N];
    BIG_INT(){len=1;memset(a,0,sizeof a),a[1]=1;}
    short& operator[](int x) {return a[x];}
    BIG_INT operator+(BIG_INT b)
    {
        BIG_INT c;
        int l=max(len,b.len);
        int jw=0;
        for (int i=1;i<=len;i++)
        {
            int now=a[i]+b[i]+jw;
            c[i]=now%10,jw=now/10;
        }
        c.len=l;
        while (jw) c[++c.len]=jw%10,jw/=10;
        return c;
    }
    friend int comp(BIG_INT x,BIG_INT y)
    {
        if (x.len!=y.len) return x.len<y.len;
        for (int i=x.len;i>=1;i--) if (x[i]!=y[i]) return x[i]<y[i];
        return -1;
    }
    friend int operator-(BIG_INT x,BIG_INT y)
    {
        if (comp(x,y)==1) swap(x,y);
        int ret=0;
        int jw=0,nw=1;
        for (int i=1;i<=x.len;i++)
        {
            int now=x[i]+jw;
            if (now<y[i]) jw=-1,now+=10;
            else jw=0;
            ret+=nw*(now-y[i]);
            nw*=10;
            if (i>=18) break;
        }
        return ret;
    }
    void operator -- ()
    {
        int now=1;
        while (a[now]==0) a[now]=9,now++;
        a[now]--;
        if (now==len&&a[now]==0) len--;
    }
    void operator ++ ()
    {
        int now=1;
        while (now<=len&&a[now]==9) a[now]=0,now++;
        a[now]++;
        if (now==len+1) len=now;
    }
    BIG_INT operator/(int x)
    {
        BIG_INT c;
        int jw=0;
        for (int i=len;i>=1;i--)
        {
            int now=a[i]+jw;
            c[i]=now/2;
            jw=now&1;
            jw*=10;
        }
        c.len=len;
        while (c[c.len]==0) c.len--;
        return c;
    }
}x,y;

signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>s;
    for (char c:s)
    {
        if (c=='1') dx++,x=x+x;
        else if (c=='2') dx++,x=x+x,x.operator++();
        else if (c=='U') dx--,x=x/2;
        else if (c=='L') x.operator--();
        else x.operator++();
    }
    cin>>s;
    for (char c:s)
    {
        if (c=='1') dy++,y=y+y;
        else if (c=='2') dy++,y=y+y,y.operator++();
        else if (c=='U') dy--,y=y/2;
        else if (c=='L') y.operator--();
        else y.operator++();
    }
    if (dx>dy) swap(x,y),swap(dx,dy);
    int tot=0;
    while (dy!=dx)
    {
        dy--;
        tot++;
        y=y/2;
    }
    ans=y-x+tot;
    while (comp(x,y)!=-1)
    {
        tot+=2;
        x=x/2,y=y/2;
        ans=min(ans,y-x+tot);
    }
    ans=min(ans,tot);
    cout<<ans;
}

下面讲满分做法

考虑用数组存储路径。

  • 1 :\(a_{++len}=0\)
  • 2 :\(a_{++len}=1\)
  • U :\(jw(len--)\)
  • L :\(a_{len}--\)
  • R :\(a_{len}++\)

其中的 \(jw(x)\) 是向前一步进位,可以发现 \(a\) 数组中存的每一位都变成了上下节点间的移动,没有了左右的移动,于是就有了 \(jw(x)\) 的写法。

inline void jw(int x)
{
    a[x-1]+=(a[x]>>1);//x这一层的贡献映射到上一层就是a[x]/2
    a[x]&=1;
}

注意最后要对全局进行一次进位。
现在操作已经都存下来了,那么接下来就是算答案了。
有以下代码:

//la为a操作的大小
//lb为b操作的大小
len=min(la,lb);
int now=0;
for (int i=0;i<=len&&abs(now)<=inf;i++)
{
	now=(now<<1)+a[i]-b[i];//计算两个棋子在当前这一层的间距
	ans=min(ans,abs(now)+(len-i<<1));//两个还要共同向下跳len-i层
}
cout<<ans+abs(la-lb);//更深的棋子还要单独往下跳

那么这道题就做完了。

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
using namespace std;

const int N=1e5+5,inf=1e9;
char s[N];
int a[N],la,lb,b[N],ans=inf;

inline void jwa(int x)
{
    a[x-1]+=(a[x]>>1);
    a[x]&=1;
}
inline void jwb(int x)
{
    b[x-1]+=(b[x]>>1);
    b[x]&=1;
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>s+1;
    int len=strlen(s+1);
    for (int i=1;i<=len;i++)
    {
        if (s[i]=='1') a[++la]=0;
        else if (s[i]=='2') a[++la]=1;
        else if (s[i]=='U') jwa(la),la--;
        else if (s[i]=='L') a[la]--;
        else a[la]++;
    }
    cin>>s+1;
    len=strlen(s+1);
    for (int i=1;i<=len;i++)
    {
        if (s[i]=='1') b[++lb]=0;
        else if (s[i]=='2') b[++lb]=1;
        else if (s[i]=='U') jwb(lb),lb--;
        else if (s[i]=='L') b[lb]--;
        else b[lb]++;
    }
    for (int i=la;i>1;i--) jwa(i);
    for (int i=lb;i>1;i--) jwb(i);
    len=min(la,lb);
    int now=0;
    for (int i=0;i<=len&&abs(now)<=inf;i++)
    {
        now=(now<<1)+a[i]-b[i];
        ans=min(ans,abs(now)+(len-i<<1));
    }
    cout<<ans+abs(la-lb);
    return 0;
}

标签:int,CEOI2013,P5513,++,len,--,Board,operator,now
From: https://www.cnblogs.com/Fredericm/p/LuoguP5513CWOI1114C.html

相关文章

  • Checkerboard Context Model for Efficient Learned Image Compression
    目录AbstractIntroductionPreliminary初步介绍VariationalImageCompressionwithHyperprior(超先验变分图像压缩)AutoregressiveContext(自回归上下文模型)ParallelContextModeling并行上下文模型Random-MaskModel:TestArbitraryMasks(随机掩码模型)HowDistanceInfl......
  • RandomPaintingOnABoard TopCoder - 12607
    AnoteabouttheconstraintsConstraintsindicateusthatthemaximumwidthandheightwillbe21.Thereisanotherconstraintthough:Themaximumtotalnumberofcellsis150.Thiscanhelpusbecauseitmeansthatthesmallerdimensionwillbeatmost1......
  • Allwinner SoC based boards
    AllwinnerSoCbasedboardsForboardsusinganAllwinnerARMbasedSoC("sunxi"),theU-Bootbuildsystemgeneratesasingleintegratedimagefile: u-boot-sunxi-with-spl.bin. ThisfilecanbeusedonSDcards,eMMCdevices,SPIflashandforthe......
  • [macos]keyboard mastero设置
    拖动的时候通过点击command来进行复制 ......
  • 春秋云镜 Brute4Board WP
    扫描[*]Icmpalivehostslenis:139.99.148.22:22open39.99.148.22:21open39.99.148.22:80open39.99.148.22:6379open[*]aliveportslenis:4startvulscan[*]WebTitle:http://39.99.148.22code:200len:4833title:WelcometoCentOS[+]Redis:3......
  • RT-Thread Studio刚新建工程后直接打开main.c编译就board.c里产生报错,解决办法
    如题,RT-ThreadStudio刚新建工程后直接打开main.c编译就产生报错。具体为:刚新建了一个stm32F407ZGT6和一个STM32F103RCT6的工程,之后啥代码也没有改,直接打开main.c文件然后编译,直接报错。报错定位在“drivers/board.c”,再具体定位在代码“RT_WEAK voidrt_hw_board_init()”。......
  • BootstrapBlazor组件库,Clipboard剪切板服务
    BootstrapBlazor组件库,Clipboard剪切板服务组件介绍本Blazor组件依赖于BootstrapBlazor组件库。使用该组件之前需要先安装BootstrapBlazor组件库。可以通过nuget命令行安装dotnetaddpackageBootstrapBlazor--version7.x或者双击项目名称直接添加ItemGroup<ItemGroup......
  • Sentinel-dashboard安装(k8s部署)
    目录Sentinel-dashboard安装(k8s部署)一.拉取镜像并推送到私库二.准备sentinelstatefulset部署配置文件三.部署并访问sentinelSentinel-dashboard安装(k8s部署)一.拉取镜像并推送到私库这里选择的是dockerhub已经有人制作好的Sentinel镜像dockerpullbladex/sentinel-dashboard......
  • grafana 配置自定义dashboard
    本文为博主原创,转载请注明出处:1.配置数据源         配置完成后,点击SaveAndTest,如果配置正确,页面则显示如下:           2.配置dashboard          点击Addnewpanel后,界面如下:       ......
  • 国产开发板上打造开源ThingsBoard工业网关--基于米尔芯驰MYD-JD9X开发板
    本篇测评由面包板论坛的优秀测评者“JerryZhen”提供。本文将介绍基于米尔电子MYD-JD9X开发板打造成开源的Thingsboard网关。Thingsboard网关是一个开源的软件网关,采用python作为开发语言,可以部署在任何支持python运行环境的主机上,灵活性很高,修改代码相对比较方便。它可以作为一......