【Codeforces Round #763 (Div. 2)】【题解A.B】

2021-12-29

A. Robot Cleaner

题目详情

一个机器人清洁器被放置在一个长方形房间的地板上,四周是墙壁。地板由 n n n 行和 m m m 列组成。地板的行从上到下从 1 1 1 n n n 编号,地板的列从左到右从 1 1 1 m m m 编号。第 r r r 行和第 c c c 列交叉处的单元格表示为 ( r , c ) (r,c) (r,c)。机器人的初始位置为 ( r b , c b ) (r_b,c_b) (rb,cb)

在一秒内,机器人移动dr行和dc列,即一秒后,机器人从单元格 ( r , c ) (r,c) (r,c)移动到 ( r + d r , c + d c ) (r+d_r,c+d_c) (r+dr,c+dc)。初始 d r = 1 d_r=1 dr=1 d c = 1 d_c=1 dc=1。如果移动方向有垂直墙(左墙或右墙),则在移动前反射 d c d_c dc,所以dc的新值为 − d c -d_c dc。并且如果有水平墙(上墙或下墙), d r d_r dr 在移动之前被反射,所以 d r d_r dr 的新值是 − d r -d_r dr

每一秒(包括机器人开始移动之前的那一刻),机器人都会清理与其位置位于同一行或同一列的每个单元格。在 ( r d , c d ) (r_d,c_d) (rd,cd) 处只有一个脏单元格。机器人的工作是清洁那个肮脏的牢房。

第一个示例的插图。蓝色弧线是机器人。红星是目标脏单元格。机器人每秒清理一行和一列,用黄色条纹表示。

给定地板尺寸 n 和 m,机器人的初始位置 ( r b , c b ) (r_b,c_b) (rb,cb) 和脏单元的位置 ( r d , c d ) (r_d,c_d) (rd,cd),找到机器人完成工作的时间。

输入
每个测试包含多个测试用例。第一行包含测试用例数 t ( 1 ≤ t ≤ 1 0 4 ) t (1≤t≤10^4) t(1t104)。测试用例的描述如下。

一个测试用例只有一行,包含六个整数 n , m , r b , c b , r d , 和 c d ( 1 ≤ n , m ≤ 100 , 1 ≤ r b , r d ≤ n , 1 ≤ c b , c d ≤ m ) n, m, rb, cb, rd, 和 cd (1≤n,m≤100, 1≤r_b,r_d≤n, 1≤c_b,c_d≤m) n,m,rb,cb,rd,cd(1n,m100,1rb,rdn,1cb,cdm) —房间的大小、机器人的初始位置和脏物单元的位置。

输出
对于每个测试用例,打印一个整数——机器人清洁脏单元的时间。我们可以证明机器人最终总是会清理脏的单元格。

input
5
10 10 6 1 2 8
10 10 9 9 1 1
9 8 5 6 2 1
6 9 2 2 5 8
2 2 1 1 2 1
output
7
10
9
3
0

题解:

让我们考虑这个问题的一维问题:有 n 个单元格,排成一排。 机器人位于第 x 个单元格,脏单元格位于第 y 个单元格。 每一秒,机器人都会在其位置清洁细胞。 机器人最初每秒向右移动 1 个单元格。 如果移动方向上没有单元格,则将反映其方向。 机器人清洁脏单元的最短时间是多少?

有两种情况需要考虑:

如果 x ≤ y x≤y xy,那么答案是 y − x y-x yx 。 机器人直接进入肮脏的牢房。
否则,如果 x > y x>y x>y,则机器人需要先到正确的端点,然后再回到脏单元。 到达正确的端点需要 n − x n-x nx秒钟,而从那个单元到脏单元需要 n − y n-y ny秒钟。 因此,这种情况的答案是 2 ⋅ n − x − y 2⋅n-x-y 2nxy
回到我们最初的问题,我们可以把它分成两个一维版本来解决。 这是通过将机器人和脏单元的位置投影到 x x x y y y轴上来完成的,如下所示。

通过这样做,我们可以看到我们可以清洁脏单元,当且仅当机器人的一个投影可以到达脏单元。 因此,答案是两个子问题的答案之间的最小值。

【code】:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;

const int inf = 0x3f3f3f3f;
const int maxn = 1e6 + 5;
void solve()
{
   
    ll n, m, rb, cb, rd, cd, count = 0, dr = 1, dc = 1;
    cin >> n >> m >> rb >> cb >> rd >> cd;

    while (1)
    {
   
        if (rb == rd || cb == cd)
        {
   
            break;
        }
        if (dr == 1 && rb == n)
        {
   
            dr = -1;
        }
        else if (dr == 1 && rb == 1)
        {
   
            dr = 1;
        }
        if (dc == 1 && cb == m)
        {
   
            dc = -1;
        }
        else if (dc == -1 && cb == 1)
        {
   
            dc = 1;
        }
        rb += dr;
        cb += dc;
        count++;
    }
    cout << count << endl;
}

int main()
{
   
    ios::sync_with_stdio(0);
    int t;
    cin >> t;
    while (t--)
        solve();
    return 0;
}

#include <bits/stdc++.h>
using namespace std;
 
int main() {
   
    int ntest;
    cin >> ntest;
    while (ntest--) {
   
        int n, m, rb, cb, rd, cd;
        cin >> n >> m >> rb >> cb >> rd >> cd;
        cout << min(
            rb <= rd ? rd - rb : 2 * n - rb - rd,
            cb <= cd ? cd - cb : 2 * m - cb - cd
        ) << '\n';
    }
    return 0;
}

B. Game on Ranges

题目详情:

爱丽丝和鲍勃玩以下游戏。 Alice 有一组不相交的整数范围的集合 S,最初只包含一个范围 [1,n]。在一轮中,Alice 从集合 S 中选择一个范围 [l,r] 并要求 Bob 在该范围内选择一个数字。 Bob 选择一个数字 d (l≤d≤r)。然后 Alice 从 S 中删除 [l,r] 并将范围 [l,d−1](如果 l≤d−1)和范围 [d+1,r](如果 d+1≤r )。当集合 S 为空时,游戏结束。我们可以证明每场比赛的回合数正好是 n。

玩完游戏后,Alice 记住了她从集合 S 中选择的所有范围 [l,r],但 Bob 不记得他选择的任何数字。但是 Bob 很聪明,他知道他可以从 Alice 的范围中找出他的数字 d,所以他向你寻求编程技巧方面的帮助。

给定 Alice 选择的范围列表 ([l,r]),对于每个范围,帮助 Bob 找到 Bob 选择的数字 d。

我们可以证明 Bob 总是有一种独特的方式来为 Alice 选择的有效范围列表选择他的号码。

输入
每个测试包含多个测试用例。第一行包含测试用例数 t (1≤t≤1000)。测试用例的描述如下。

每个测试用例的第一行包含一个整数 n (1≤n≤1000)。

接下来的 n 行中的每一行都包含两个整数 l 和 r (1≤l≤r≤n),表示 Alice 在某个点选择的范围 [l,r]。

请注意,范围没有按特定顺序给出。

保证所有测试用例的n之和不超过1000,每个测试用例的范围均来自有效游戏。

输出
对于每个测试用例打印 n 行。每行应包含三个整数 l、r 和 d,表示对于 Alice 的范围 [l,r],Bob 选择了数字 d。

您可以按任何顺序打印这些行。我们可以证明答案是唯一的。

不需要在每个测试用例之后打印一个新行。示例输出中的新行仅用于可读性。

input:
4
1
1 1
3
1 3
2 3
2 2
6
1 1
3 5
4 4
3 6
4 5
1 6
5
1 5
1 2
4 5
2 2
4 4


output:
1 1 1

1 3 1
2 2 2
2 3 3

1 1 1
3 5 3
4 4 4
3 6 6
4 5 5
1 6 2

1 5 3
1 2 1
4 5 5
2 2 2
4 4 4

题解:

【code】:


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;

const int inf = 0x3f3f3f3f;
const int maxn = 1e6 + 5;
void solve()
{
   
    int n;
    cin >> n;
    map<pair<int, int>, bool> mp;
    vector<int> l(n), r(n);
    for (int i = 0; i < n; i++)
    {
   
        cin >> l[i] >> r[i];
        mp[{
   l[i], r[i]}] = 1;
    }
    for (int i = 0; i < n; i++)
    {
   
        for (int j = l[i]; j <= r[i]; j++)
        {
   
            if ((j == l[i] || mp[{
   l[i], j - 1}]) && (j == r[i] || mp[{
   j + 1, r[i]}]))
            {
   
                cout << l[i] << " " << r[i] << " " << j << endl;
                break;
            }
        }
    }
}

int main()
{
   
    ios::sync_with_stdio(0);
    int t;
    cin >> t;
    while (t--)
        solve();
    return 0;
}

全部评论

相关推荐

点赞 评论 收藏
分享
避坑恶心到我了大家好,今天我想跟大家聊聊我在成都千子成智能科技有限公司(以下简称千子成)的求职经历,希望能给大家一些参考。千子成的母公司是“同创主悦”,主要经营各种产品,比如菜刀、POS机、电话卡等等。听起来是不是有点像地推销售公司?没错,就是那种类型的公司。我当时刚毕业,急需一份临时工作,所以在BOSS上看到了千子成的招聘信息。他们承诺无责底薪5000元,还包住宿,这吸引了我。面试的时候,HR也说了同样的话,感觉挺靠谱的。于是,我满怀期待地等待结果。结果出来后,我通过了面试,第二天就收到了试岗通知。试岗的内容就是地推销售,公司划定一个区域,然后你就得见人就问,问店铺、问路人,一直问到他们有意向为止。如果他们有兴趣,你就得摇同事帮忙推动,促进成交。说说一天的工作安排吧。工作时间是从早上8:30到晚上18:30。早上7点有人叫你起床,收拾后去公司,然后唱歌跳舞(销售公司都这样),7:55早课(类似宣誓),8:05同事间联系销售话术,8:15分享销售技巧,8:30经理训话。9:20左右从公司下市场,公交、地铁、自行车自费。到了市场大概10点左右,开始地推工作。中午吃饭时间大约是12:00,公司附近的路边盖饭面馆店自费AA,吃饭时间大约40分钟左右。吃完饭后继续地推工作,没有所谓的固定中午午休时间。下午6点下班后返回公司,不能直接下班,需要与同事交流话术,经理讲话洗脑。正常情况下9点下班。整个上班的一天中,早上到公司就是站着的,到晚上下班前都是站着。每天步数2万步以上。公司员工没有自己的工位,百来号人挤在一个20平方米的空间里听经理洗脑。白天就在市场上奔波,公司的投入成本几乎只有租金和工资,没有中央空调。早上2小时,晚上加班2小时,纯蒸桑拿。没有任何福利,节假日也没有3倍工资之类的。偶尔会有冲的酸梅汤和西瓜什么的。公司的晋升路径也很有意思:新人—组长—领队—主管—副经理—经理。要求是业绩和团队人数,类似传销模式,把人留下来。新人不能加微信、不能吐槽公司、不能有负面情绪、不能谈恋爱、不能说累。在公司没有任何坐的地方,不能依墙而坐。早上吃早饭在公司外面的安全通道,未到上班时间还会让你吃快些不能磨蹭。总之就是想榨干你。复试的时候,带你的师傅会给你营造一个钱多事少离家近的工作氛围,吹嘘工资有多高、还能吹自己毕业于好大学。然后让你早点来公司、无偿加班、抓住你可能不会走的心思进一步压榨你。总之,大家在找工作的时候一定要擦亮眼睛,避免踩坑!———来自网友
qq乃乃好喝到咩噗茶:不要做没有专业门槛的工作
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务