【coci2011/2012 3】距离之和

本文介绍了如何解决一个与机器人移动和计算曼哈顿距离之和相关的问题。给定一个二维空间中机器人的移动指令和固定控制点,计算每次指令后所有控制点到机器人的曼哈顿距离总和。通过预处理和动态更新,可以有效地避免暴力求解导致的超时。文章提供了思路和正解,并提示了如何处理不同指令对距离总和的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【coci2011/2012 3】距离之和

题目:

Mirko创造了一个新的机器人并且决定去测试一下。我们可以想象测试的跑道是一个二维的空间。初始的时候,机器人在(0,0)的位置,在收到了一系列命令之后,机器人就会移动,这些命令是S,J,I,Z,每个命令代表了不同的移动方向。
具体一下,如果机器人原来在(x,y)的位置,在收到了S的命令之后,会向(x,y+1)移动,收到J之后,会向(x,y-1)移动,收到I命令之后会向(x+1,y)移动,收到Z命令之后会向(x-1,y)移动。
在这个二维空间上有N个固定的控制点,在每个命令执行之后,每个固定点就会计算自己与机器人的曼哈顿距离,然后把这些距离的总和返回给Mirko。
说明:两个点(x1,y1)和(x2,y2)的曼哈顿是|x1-x2|+|y1-y2|。

输入:

第一行是正整数N(1<=N<=100000)和M(1<=M<=300000),N表示控制点的个数,M表示命令的数量。
接下来N行,每行两个整数(绝对值不大于1000000),表示控制点的坐标,有些控制点可能是相同的。接下来一行,一个长度为M的字符串(包含以上四种命令),表示机器人依次收到的命令。

输出:

输出M行,每行一个整数,对于第i行,输出的是第i个命令执行以后所有控制点与机器人的曼哈顿距离之和。


乍一看,暴力肯定会超时

可以坑50%数据点

不过正解也很明显

我们一开始就把当前的曼哈顿之和先算出来

记录行和列上的控制点的个数

把它弄一个前缀和

之后用x和y记录当前机器人的坐标

我们每次得到一个操作,便根据情况从ans里减掉一些,加上一些就可以了

‘S’:

+ lq[y];//lq为列的前缀和,hq为行的前缀和,l为每列的操作点的个数,h为每行操作点的个数

- (n-lq[y]);//n为点的总数

'J':

+ n-lq[y]+l[y]

- (lq[y]-l[y])

'I':

+ hq[x]

- (n-hq[x])

'Z':

+ n-hq[x]+h[x]

- (hq[x]-h[x])


标程:(请勿抄袭,后果很严重)

var     hq,lq,h,l:array[-1000001..1000001]of longint;
        ch:char;
        x,y,n,m,i,j,k,s,nx,ny:longint;
        ans:int64;
begin
        assign(input,'robot.in');
        assign(output,'robot.out');
        reset(input);
        rewrite(output);
        readln(n,m);
        for i:=1 to n do
        begin
                readln(x,y);
                inc(h[x]);
                inc(l[y]);
                ans:=ans+abs(x-0)+abs(y-0);
        end;
        for i:=-1000000 to 1000000 do
        begin
                lq[i]:=lq[i-1]+l[i];
                hq[i]:=hq[i-1]+h[i];
        end;
        nx:=0;
        ny:=0;
        for i:=1 to m do
        begin
                read(ch);
                case ch of
                'S':
                begin
                        ans:=ans+lq[ny];
                        ans:=ans-(n-lq[ny]);
                        inc(ny);
                end;
                'J':
                begin
                        ans:=ans-(lq[ny]-l[ny]);
                        ans:=ans+(n-(lq[ny]-l[ny]));
                        dec(ny);
                end;
                'I':
                begin
                        ans:=ans+hq[nx];
                        ans:=ans-(n-hq[nx]);
                        inc(nx);
                end;
                'Z':
                begin
                        ans:=ans-(hq[nx]-h[nx]);
                        ans:=ans+(n-(hq[nx]-h[nx]));
                        dec(nx);
                end;
                end;
                writeln(ans);
        end;
        close(input);
        close(output);
end.


### 回答1: 题目描述: Eko 有一排树,每棵树的高度不同。他想要砍掉一些树,使得剩下的树的高度都相同。他希望砍掉的树的高度尽可能地少,你能帮他算出最少要砍掉多少棵树吗? 输入格式: 第一行包含两个整数 N 和 M,分别表示树的数量和 Eko 希望的树的高度。 第行包含 N 个整数,表示每棵树的高度。 输出格式: 输出一个整数,表示最少要砍掉的树的数量。 输入样例: 9 5 2 3 4 7 8 9 10 11 12 输出样例: 3 解题思路: 分答案 首先,我们可以发现,如果我们知道了 Eko 希望的树的高度,那么我们就可以计算出砍掉多少棵树。 具体来说,我们可以遍历每棵树,如果它的高度大于 Eko 希望的树的高度,那么就将它砍掉,否则就保留它。 然后,我们可以使用分答案的方法来确定 Eko 希望的树的高度。 具体来说,我们可以将树的高度排序,然后一个可能的 Eko 希望的树的高度,然后计算砍掉多少棵树,如果砍掉的树的数量小于等于 M,那么说明 Eko 希望的树的高度可能更小,否则说明 Eko 希望的树的高度可能更大。 最后,我们可以得到最少要砍掉的树的数量。 时间复杂度:O(NlogN)。 参考代码: ### 回答2: 这道题目是一道模拟题,需要模拟机器人的移动过程以及得出最终机器人的位置和朝向。首先需要明确机器人的起始位置以及朝向,其次需要读取输入的指令,根据指令逐步移动机器人,并顺便判断是否会越界或者碰到障碍物。最后输出最终机器人的位置和朝向。 在本题中,需要按照从西向东、从北向南、从东向西、从南向北的顺序判断机器人的朝向。为了方便表述,我把机器人的朝向表示为0、1、2、3,分别代表从西向东、从北向南、从东向西、从南向北。 具体地说,机器人按照指令逐步移动时需要分情况讨论,比如: 1.当前机器人朝向为0,即从西向东: 若指令为F,则x坐标+1,但需要判断是否越界或者碰到障碍物。 若指令为L,则朝向变为3。 若指令为R,则朝向变为1。 2.当前机器人朝向为1,即从北向南: 若指令为F,则y坐标-1,但需要判断是否越界或者碰到障碍物。 若指令为L,则朝向变为0。 若指令为R,则朝向变为2。 3.当前机器人朝向为2,即从东向西: 若指令为F,则x坐标-1,但需要判断是否越界或者碰到障碍物。 若指令为L,则朝向变为1。 若指令为R,则朝向变为3。 4.当前机器人朝向为3,即从南向北: 若指令为F,则y坐标+1,但需要判断是否越界或者碰到障碍物。 若指令为L,则朝向变为2。 若指令为R,则朝向变为0。 最后输出最终机器人的位置和朝向即可。 在编写程序时需要注意判断边界和障碍物,以及要用scanf读取输入,不要用C++的cin,否则会TLE。此外,由于本题没有给出边界和障碍物,需要自己设置。最后,本题的思路不难,但是需要认真仔细地处理各种情况,多测试几组数据找出程序的漏洞,这样才能通过本题。 ### 回答3: 本题为一道组合数学题,需要运用排列组合知识进行分析。 题目要求将n个方块填入3*3的网格中,每个方块可以是红色、绿色或蓝色的一个。要求每行、每列和对角线上的方块颜色都不相同。求方案总数。 首先考虑对第一行进行颜色选取。由于第一行每个位置的颜色都不影响其他行和列,故第一行的颜色选取不影响总方案数。所以假设第一行颜色已经确定,考虑第行的颜色选取。第行中各位置的颜色受到第一行的限制,只有第一行某位置颜色的补集才能选取。例如,若第一行第一个位置是红色,那么第行第一个位置不能选取红色。因为每行颜色不能相同,所以第行受到第一行限制的位置只有3个。第三行同理,由于前两行的限制,只有2个位置可选。做完颜色选取后,再将每行的方块进行排列,此时我们可以使用错排公式得到方案数: D(n) = n!(1 - 1/1! + 1/2! - 1/3! + ... + (-1)^(n)/n!) 最终,方案总数即为每个第一行颜色选取方法下的错排方案数之和。按题意枚举第一行的颜色,就可以得到最终的方案总数了。 总结一下,本题所需要的知识点为:错排公式、颜色限制对组合数的影响、暴力枚举法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值