Codeforces Round #389 (Div. 2, Rated, Based on Technocup 2017 - Elimination Round 3) 总结

来源:互联网 发布:wildfly 端口配置 编辑:程序博客网 时间:2024/06/05 22:28

这场真是GG,比赛的时候就写出了三道题,还都比较水(可怜的standing才2000 QωQ)。

A. Santa Claus and a Place in a Class

这里写图片描述这里写图片描述

题意:有一个n*m的区域,每个位置有一个桌子,桌子有两个座位,座位上都有数字,如图排列(一个桌子左右为相邻数字,桌子间竖向排列)。给出一个数字k,问对应的座位在第r列的第d个,以及在某桌的左面还是右面(’L’ / ‘R’)。

解法:直接计算。先不论左/右,设t = (k + 1)/ 2,则r = k / m + 1; d = k % m,处理一下=0的情况;k是奇数在左,偶数在右。

代码:

#include <bits/stdc++.h>using namespace std;int main(){    //freopen (".in", "r", stdin);    //freopen (".out", "w", stdout);    int n, m, k;    scanf ("%d%d%d", &n, &m, &k);    int pl = (k + 1)/ 2;    int r = pl / m;    if (pl % m) ++ r;    int d = pl % m;    if (d == 0)        d += m;    cout << r << " "<< d << " ";    if (k & 1) cout << "L"<<endl;    else cout << "R"<<endl;    return 0;}

B. Santa Claus and Keyboard Check

这里写图片描述这里写图片描述

题意:(苯蒟蒻英语+理解能力不好,只知道大概意思???)一个键盘,一个人期望打出一个字符串s,实际打出来的t,可以交换键盘上任意两个键,目的使s变成t。问交换次数k,以及每次交换的两个键;若无解输出-1。

解法1:直接输出-1,由于这是cf,得不到分。(扯一句~~~)
解法2(真的是解法!!!):模拟。统计s中每一个字符在t中对应位置的字符,如果不是自己,就交换那s和t那个位置上那两个键,统计次数,如果有一种字母对应多种字母(如:s: aa; t: ab),就输出-1。应该还要从t到s对应一遍,保证不会一对多或多对一。(map更好做一些???)

代码:

#include <bits/stdc++.h>using namespace std;char s[1005], t[1005];int dy[35];bool pd[35];int ans[1005];int main(){    //freopen (".in", "r", stdin);    //freopen (".out", "w", stdout);    int k = 0, n;    scanf ("%s%s", s + 1, t + 1);    n = strlen (s + 1);    for (int i = 1; i <= n; ++ i) {        if (dy[s[i] - 'a' + 1] != 0 && dy[s[i] - 'a' + 1] != t[i] - 'a' + 1){            puts("-1");            return 0;        }        if (dy[t[i] - 'a' + 1] != 0 && dy[t[i] - 'a' + 1] != s[i] - 'a' + 1){            puts("-1");            return 0;        }        dy[s[i] - 'a' + 1] = t[i] - 'a' + 1;        dy[t[i] - 'a' + 1] = s[i] - 'a' + 1;    }    for (int i = 1; i <= 26; ++ i) if (!dy[i]) dy[i] = i;    for (int i = 1; i <= 26; ++ i)        if (dy[i] != i && !pd[dy[i]] && !pd[i]) {            ans[++ k] = i;            pd[i] = pd[dy[i]] = 1;        }    cout << k << endl;    for (int i = 1; i <= k; ++ i){        printf("%c %c\n", char(ans[i] + 'a' - 1), char(dy[ans[i]] + 'a' - 1));    }    return 0;}

C. Santa Claus and Robot

这里写图片描述这里写图片描述这里写图片描述这里写图片描述

题意:有一个可以沿着网格线行走的机器人。给出个长度为n,由’L’ / ‘R’ / ‘U’ / ‘D’组成的字符串,分别对应上/下/左/右,表示机器人n次移动的方向。p0为起点,p1,p2…pm都是路径上的点(未给出,可重复),并且机器人依次经过p0 -> p1; p1 -> p2; … p(m - 1) -> pm走的都是最短路径,问m的最小值。

解法:模拟行走过程,贪心。last点表示上一个p中的点,直到碰到一个点,last到它走过的路程 > 它们的曼哈顿距离,last更新为上一个点,答案+1,注意加上最后一个点。(据说判断是否有反向边好写???)

代码:

#include <bits/stdc++.h>using namespace std;struct point {    int x, y;}p[200005];char s[200005];int main(){    //freopen (".in", "r", stdin);    //freopen (".out", "w", stdout);    int n, last = 0, dis = 0, ans = 1;    scanf ("%d%s", &n, s + 1);    p[0].x = p[0].y = 0;    for (int i = 1; i <= n; ++ i)    {        if (s[i] == 'L') p[i].x = p[i - 1].x - 1, p[i].y = p[i - 1].y;        if (s[i] == 'R') p[i].x = p[i - 1].x + 1, p[i].y = p[i - 1].y;        if (s[i] == 'U') p[i].y = p[i - 1].y + 1, p[i].x = p[i - 1].x;        if (s[i] == 'D') p[i].y = p[i - 1].y - 1, p[i].x = p[i - 1].x;        dis += 1;        if (dis > abs(p[i].x - p[last].x) + abs(p[i].y - p[last].y)){            ++ ans;            last = i - 1;            dis = 1;        }    }    printf ("%d\n", ans);    return 0;}
0 0
原创粉丝点击