ABC341 A-G

Toyota Programming Contest 2024#2(AtCoder Beginner Contest 341) - AtCoder

B读不懂题卡了,F读假题卡了,开题开慢了rank++了

A - Print 341

题意:

打印一串交替出现的包含N个0,N+1个1的01串

代码:

void solve()
{
    int n;
    scanf("%d", &n);
    for (int i = 1; i <= n; ++i)
        printf("10");
    printf("1");
}

B - Foreign Exchange

题意:

有N个国家的货币,每个国家的货币初始有Ai个,国家 i 的货币可以换为国家 i + 1 的货币,比例为Si : Ti,问最多能拥有多少国家N的货币

题解:

从前往后尽量换完换即可

LL a[N];
void solve()
{
    int n;
    scanf("%d", &n);
    for (int i = 1; i <= n; ++i)
        scanf("%lld", &a[i]);
    for (int i = 1; i < n; ++i)
    {
        LL s, t;
        scanf("%lld%lld", &s, &t);
        t *= a[i] / s;
        a[i + 1] += t;
    }
    printf("%lld\n", a[n]);
}

C - Takahashi Gets Lost

题意:

给出N行M列的图,'.'表示可以经过的格子,'#'表示不能经过的格子,给出一串指令集,包含LRUD四种指令(分别表示往左右上下走,具体解释见原题),问有多少个初始位置能满足执行以上一串指令时不经过'#'

题解:

500^3暴力即可

char op[N], mp[N][N];
int check(int x, int y)
{
    int i = 1;
    while (op[i])
    {
        if (mp[x][y] == '#')return 0;
        if (op[i] == 'L')y -= 1;
        if (op[i] == 'R')y += 1;
        if (op[i] == 'U')x -= 1;
        if (op[i] == 'D')x += 1;
        ++i;
    }
    return mp[x][y] == '.';
}
void solve()
{
    int n, m, t;
    scanf("%d%d%d%s", &n, &m, &t, op + 1);
    for (int i = 0; i <= n + 1; ++i)
    {
        for (int j = 0; j <= m + 1; ++j)
            mp[i][j] = '#';
    }
    for (int i = 1; i <= n; ++i)
    {
        getchar();
        for (int j = 1; j <= m; ++j)
            mp[i][j] = getchar();
    }
    int ans = 0;
    for (int i = 1; i <= n; ++i)
    {
        for (int j = 1; j <= m; ++j)
            ans += check(i, j);
    }
    printf("%d\n", ans);
}

D - Only one of two

题意:

找出第k个是n的倍数或者是m的倍数切不同时是n,m的倍数的数

题解:

关于x是第几个数可以直接通过容斥求得:f(x) = x / n + x / m - 2 * (x / lcm(n, m)),然后二分答案即可

LL n, m, k, lcm;
LL gcd(LL x, LL y)
{
    return y ? gcd(y, x % y) : x;
}
LL check(LL x)
{
    return x / n + x / m - 2 * (x / lcm);
}
void solve()
{
    scanf("%lld%lld%lld", &n, &m, &k);
    lcm = n * m / gcd(n, m);
    LL l = 0, r = 2e18;
    while (l < r)
    {
        LL mid = l + r >> 1;
        if (check(mid) < k)
            l = mid + 1;
        else
            r = mid;
    }
    printf("%lld\n", l);
}

E - Alternating String

题意:

给出一个长度为n的01串,当一个01串被称为好的必须符合以下条件:任意相邻数字不同(01交替出现)。你需要对这个01串进行m次询问,询问分为两种

1 L R:反转区间L到R内的元素(0变成1,1变成0)

2 L R:查询L到R的子串是否是好的

题解:

我们可以仅考虑对于每对相邻元素是否相同,不考虑具体每个元素是0还是1,对于修改操作仅会使得(l - 1, l)与(r, r + 1)这两对相邻元素是否相同的性质反转,我们可以用一个set存所有相同的相邻元素位置(如存左边的元素下标)。对于修改操作我们仅需查询set内是否已经存在l - 1,若存在则删除,不存在则加入,右边同理,这样维护这个集合。对于查询操作我们仅需查询set中是否不存在l, r - 1范围的元素即可(set是支持二分查找的,可以通过*st.lower_bound(l) >= r 求得)

char ch[N];
set<int>st;
void solve()
{
    int n, m;
    scanf("%d%d%s", &n, &m, ch + 1);
    for (int i = 1; i < n; ++i)
    {
        if (ch[i] == ch[i + 1])
            st.insert(i);
    }
    while (m--)
    {
        int op, l, r;
        scanf("%d%d%d", &op, &l, &r);
        if (op == 1)
        {
            if (st.find(l - 1) != st.end())
                st.erase(l - 1);
            else
                st.insert(l - 1);
            if (st.find(r) != st.end())
                st.erase(r);
            else
                st.insert(r);
        }
        else
        {
            auto it = st.lower_bound(l);
            if (it == st.end() || *it >= r)
                printf("Yes\n");
            else
                printf("No\n");
        }
    }
}

F - Breakdown

题意:

给出一张n个点m条边的无向简单图,每个点都有一个权值Wi,初始每个点上面都放有Ai个棋子,你需要进行以下操作直至棋盘上没有棋子:

选择一个棋子,删除它,记改棋子所在点的编号为x,选择一个点集S,需要使得集合内的所有点与点x相邻,且\sum _{y\in S}W_{y}<W_{x},并在每个属于点集S的点放上一颗棋子

求最大的操作次数

应该也可以线段树做(可能能写类似于维护最大区段和的写法),但上面做法更简单就懒得想了

题解:

背包DP,我们可以对每个点求一个 Si 表示在这个点上放一个棋子最多能进行多少次操作,与它相连的 x 个点看为 x 个物品,每个物品 j 的重量为 wj ,价值为 sj ,当前节点的容量为 wi - 1 ,显然这是一个01背包问题。

其次我们需要按 Wi 的值从小到大依次求每个点的 Si ,因为当我们求 i 点的 Si 时只会用到 Wj < Wi 的点做背包,只有当所有 Wj < Wi 的点的 Sj 才能求 Si

int w[N];
PII t[N];
vector<int>e[N];
LL s[N];
void solve()
{
    int n, m;
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= m; ++i)
    {
        int u, v;
        scanf("%d%d", &u, &v);
        e[u].push_back(v);
        e[v].push_back(u);
    }
    for (int i = 1; i <= n; ++i)
    {
        scanf("%d", &w[i]);
        t[i] = { w[i],i };
    }
    sort(t + 1, t + 1 + n);
    for (int i = 1; i <= n; ++i)
    {
        int u = t[i].second;
        vector<LL>dp(w[u]);
        for (auto v : e[u])
        {
            for (int j = w[u] - 1; j >= w[v]; --j)
                dp[j] = max(dp[j], dp[j - w[v]] + s[v]);
        }
        for (auto j : dp)
            s[u] = max(s[u], j + 1);
    }
    LL ans = 0;
    for (int i = 1, x; i <= n; ++i)
        scanf("%d", &x), ans += x * s[i];
    printf("%lld\n", ans);
}

G - Highest Ratio

题意:

给出一个长度为N的数组,对于每个左端点求最大子段平均值

题解:

赛时不会做,赛后看群友说的:

记 Si 为前 i 个元素的前缀和,在平面上放N个点(i, Si),第 x 个点到第 y 个点连线的斜率即为区间(x + 1, y)的平均值(平均值 = (Sy - Sx) / (y - x) = 斜率),在这个图上求凸包即可

double cross(PLL x, PLL y)//向量叉乘,直接乘好像会爆longlong用了double
{
    return (double)x.first * y.second - (double)x.second * y.first;
}
PLL operator-(PLL x, PLL y)//重载向量减法
{
    return { x.first - y.first,x.second - y.second };
}
double fun(PLL v)//求向量斜率
{
    return (double)v.second / v.first;
}
LL s[N];
double ans[N];
void solve()
{
    int n;
    scanf("%d", &n);
    for (int i = 1; i <= n; ++i)
        scanf("%d", &s[i]), s[i] += s[i - 1];
    vector<PLL>v{ {n,s[n]} };
    for (int i = n - 1; i >= 0; --i)
    {
        PLL x = { i,s[i] };
        while (v.size() > 1)//典 凸包板子
        {
            PLL y = v.back(), z = v[v.size() - 2];
            if (cross(y - x, z - y) < 0)break;
            v.pop_back();
        }
        ans[i + 1] = fun(v.back() - x);
        v.push_back({ i,s[i] });
    }
    for (int i = 1; i <= n; ++i)
        printf("%.10lf\n", ans[i]);
}

  • 52
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
更新说明: 2017-02-04(yaya) Ls command: Empty Folder returns false. 2016-12-08(yaya) 修正lz4、vhd不显示解压缩进度指示。增加lzma解压缩进度指示。 2016-11-09(不点) 0x8205 bit 5 = 1: 使checkkey闲置循环停止指令。 2016-04-13(yaya) 支持动画菜单 setmenu --graphic-entry=类型=菜单行数=菜单列数=图形宽(像素)=图形高(像素)=菜单行间距(像素) 菜单项0的路径文件名 类型: 位0:高亮指定颜色 位1:高亮颜色翻转 位2:高亮显示线框 位7:背景透明(最好使用黑色背景) 文件名: *n.??? 格式 n=00-99 高亮颜色由 color HIGHLIGHT=0xrrggbb 指定。 字符可以使用任意字型、字高、颜色,可以辅以图标。 2016-03-25(yaya) 菜单字符可以使用不同字型。 例如:"七" 使用不同字型,将 .hex 文件中的 unicode 码 “4e03” 修改为 “0080”, 将菜单中的 "七" 修改为 “\X0080”。 2016-03-23(yaya) 增强 echo 函数功能。 例如:echo -e \x18 显示 UTF-8 字符 0x18。 echo -e \X2191 显示 unicode 字符 0x2191。 2016-03-15(yaya) 1.增加动画控制热键 F2:播放/停止。 2.增加动画控制位 0x835b,位0:0/1=停止/播放。 3.增加精简字库模式:--simp=起始0,终止0,...,起始3,终止3 中文可以使用 --simp= ,内置字库应当包含 DotSize=[font_h],['simp'] 例如:font --font-high=24 --simp= /24_24.hex DotSize=24,simp 不使用热键: 可以加载 32*32 unifont 全字库 使用热键: 可以加载 24*24 unifont 全字库 使用精简字库: 可以加载 46*46 汉字全字库 使用精简字库及热键:可以加载 40*40 汉字全字库 4.不再支持 bin 格式字库。 2016-03-03(yaya) 1.增加图像背景色设置方法。 splashimage --fill-color=[0xrrggbb] 作用之一,作为小图像的背景。 作用之二,直接作为菜单的背景(即不加载图像背景)。此时只设置字体的前景色即可。 2.增加动画菜单。 splashimage --animated=[type]=[delay]=[last_num]=[x]=[y] START_FILE 类型[type]:bit 0-3: 播放次数 bit 4: 永远重复 bit 7: 透明背景 type=00:禁止播放 播放n次:序列图像各显示n次,时间独占。可作为启动前导、序幕。 永远重复:序列图像无限循环,时间与菜单共享。可作为菜单里的动画。 背景透明:即抠像。要求4角像素为背景色。 背景色最好为白色或黑色,这样可以去除一些灰色杂波。若是彩色背景,则应当非常干净。 提醒:请以16进制方式输入。否则易错。 延迟[delay]:序列图像之间的延迟。单位是滴答,即1/18.2秒。 序列数[last_num]:序列图像总数(2位数,从1开始计数)。 偏移[x]、[y]:图像偏移,单位像素。 起始图像文件 START_FILE 命名规则:*n.??? n: 1-9 或 01-99 或 001-999。 3.增加固定图像的背景色可以透明。 splashimage [--offset=[type]=[x]=[y]] FILE 类型[type]:bit 7: 透明背景 2016-02-14(yaya) setmenu 函数增加菜单项目背景短/满参数(默认短) 2016-01-19(yaya) splashimage 函数增加图像起始偏移(默认0) 2015-08-20(yaya) 1.支持非
ABC**DE*G**F***是一个按先序遍历输入的字符序列。根据引用中的描述,我们可以根据这个序列建立二叉树并按中序和后序的方式遍历。 首先,根据先序遍历的顺序建立二叉树。在先序遍历中,首先访问根节点A,然后根据先序遍历的顺序,我们可以确定A的左子树是B和C,而右子树为空。继续遍历B和C的子树,我们可以确定B的左子树为空,右子树为D和E;C的左子树为空,右子树为G。最后,遍历D、E和G的子树,我们可以确定D的左子树为空,右子树为空;E的左子树为空,右子树为空;G的左子树为空,右子树为F。这样我们就建立了如下的二叉树: ``` A / \ B C \ \ D G \ E \ F ``` 接下来,我们可以按中序遍历的方式遍历这棵树。中序遍历的顺序是左子树-根节点-右子树。所以按中序遍历的顺序,我们首先访问左子树B,然后访问根节点A,接着访问右子树D,再访问根节点B,然后访问右子树E,接着访问根节点D,然后访问右子树F,接着访问根节点E,然后访问右子树C,接着访问根节点G,最后访问右子树C。所以按中序遍历的顺序,结果是B-A-D-E-F-C-G。 最后,我们按后序遍历的方式遍历这棵树。后序遍历的顺序是左子树-右子树-根节点。所以按后序遍历的顺序,我们首先访问左子树B,然后访问右子树D,接着访问根节点E,再访问右子树F,接着访问根节点D,然后访问右子树B,接着访问根节点G,最后访问右子树C,然后访问根节点C,最后访问根节点A。所以按后序遍历的顺序,结果是B-D-E-F-D-B-G-C-A。 综上所述,按中序遍历的方式遍历该二叉树的结果是B-A-D-E-F-C-G,按后序遍历的方式遍历该二叉树的结果是B-D-E-F-D-B-G-C-A。<span class="em">1</span><span class="em">2</span><span class="em">3</span><span class="em">4</span>

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值