Educational Codeforces Round 99 (Rated for Div. 2)(A-E)

 A. Strange Functions(水题)

题意:求 [1, n] 中有多少不同的 g(x) 值,g(x) = \frac{x}{f(f(x))}

发现 g(x) 的值表示的是 10的 该数后缀0个数 次幂,只有后缀0个数改变时g(x)的值才会变化,所以直接输出n的位数

(看题干嘛 看样例

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const double eps = 1e-8;
const double PI = acos(-1.0);
const int N = 35;
const int mod = 998244353;
const int inf = 0x3f3f3f3f;

int main() {
    int t;
    string s;
    scanf("%d", &t);
    while(t--) {
        cin >> s;
        cout << s.size() << '\n';
    }
    return 0;
}

B. Jumps (思维)

题意:要从x轴的0位置移动到x位置,第 i 次移动可以选择向左移动一个单位或者向右移动 i 个单位,问最少需要几次移动。

思路:发现先向右走 i - 1 步和向右走 i 步之间的步数可以由把 i 步中的某一步换成 -1 来凑成,i 步的总位移为1 + 2 + 3 + ... + i,把某一步换掉即从总步数的基础上 -2、-3、... - i - 1,但是 -1不可以,所以-1直接向左走一步。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const double eps = 1e-8;
const double PI = acos(-1.0);
const int N = 1415;
const int mod = 998244353;
const int inf = 0x3f3f3f3f;

int main() {
    int t, n;
    scanf("%d", &t);
    while(t--) {
        scanf("%d", &n);
        int stp = 0;
        while(n > 0) n -= ++stp;
        if(n == -1) stp++;
        printf("%d\n", stp);
    }
    return 0;
}

C. Ping-pong(思维)

题意:两个人打兵乓球,接球和发球都会消耗一点体力,在接球时可以选择接或不接,每一轮最后没有接球的那个人输,上一轮获胜的人在下一轮发球,直到两人体力都变为0时游戏结束。现给出两个人的体力值,他们首先最大化自己的获胜次数,其次最小化对方的获胜次数,问最终他们的获胜次数。

思路:alice先发球,并且总是处在被动地位,bob要最大化自己的获胜次数,最优策略就是让自己的所有体力都做出贡献,他可以一直不回球,直至把alice的体力耗完,让alice无法回球,剩下的回合都是bob胜,即bob获胜y次,alice获胜 x - 1 次(最后一点体力发的球被bob接了,无法回球)

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const double eps = 1e-8;
const double PI = acos(-1.0);
const int N = 1415;
const int mod = 998244353;
const int inf = 0x3f3f3f3f;

int main() {
    int t, x, y;
    scanf("%d", &t);
    while(t--) {
        scanf("%d%d", &x, &y);
        printf("%d %d\n", x - 1, y);
    }
    return 0;
}

D. Sequence and Swaps

题意:给一个x和一个序列,每次操作可以把序列种一个大于x的数和x交换,问至少多少次把序列变为非递减的,或者输出不能实现。

思路:序列中共有 cnt 对 a[i - 1] > a[i],从左向右扫一遍,如果当前 cnt > 0 且 a[i] > x,就要进行交换。具体看代码。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 510;
const int inf = 0x3f3f3f3f;
const int mod = 1e9 + 7;

int a[N];

int main() {
    int t, n, x;
    scanf("%d", &t);
    while(t--) {
        int cnt = 0;
        scanf("%d%d", &n, &x);
        for(int i = 1; i <= n; ++i) {
            scanf("%d", &a[i]);
            if(i > 1 && a[i - 1] > a[i]) cnt++;
        }
        if(!cnt) {
            printf("0\n");
            continue;
        }
        int ans = 0;
        for(int i = 1; i <= n; ++i) {
            if(cnt > 0 && a[i] > x) {
                if(i > 0 && a[i - 1] > a[i]) cnt--;
                if(i < n && a[i] > a[i + 1]) cnt--;
                swap(a[i], x);
                if(i > 0 && a[i - 1] > a[i]) cnt++;
                if(i < n && a[i] > a[i + 1]) cnt++;
                ans++;
            }
        }
        printf("%d\n", !cnt ? ans : -1);
    }
    return 0;
}

E. Four Points(思维 + 枚举)

题意:给四个点,通过移动使这四个点构成一个和坐标轴平行的正方形,问最小的移动步数。

思路:

设p1、p2、p3、p4分别为最终要作为正方形左下角、右下角、右上角、左上角的点,首先枚举4个点的排列,共 4! 种。

再枚举边长,为使步数最小,正方形的边长一定是某两点横坐标之差或纵坐标之差,共12种。

现在确定了每个点的相对位置和正方形的边长,求构成这种正方形的最小步数,等价于固定一个点不动,让其他三个点和该点重合的步数,如图:

可以先把它们的目标相对距离减掉,也就是p2.x -= d,p3.x -= d,p3.y -= d,p4.y -= d,再把得到的四个新坐标移动到一点,把横纵坐标分开考虑,也就是把4个数变成相同的,取中位数即可。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5 + 10;
const ll inf = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 + 7;

ll x[5], y[5], dis[20], xx[5], yy[5];

int main() {
    int t, p[5];
    for(int i = 1; i <= 4; ++i) p[i] = i;
    scanf("%d", &t);
    while(t--) {
        int tot = 0;
        for(int i = 1; i <= 4; ++i) {
            scanf("%lld%lld", &x[i], &y[i]);
            for(int j = 1; j < i; ++j) {
                dis[++tot] = abs(x[i] - x[j]);
                dis[++tot] = abs(y[i] - y[j]);
            }
        }
        ll ans = inf;
        do {
            for(int i = 1; i <= tot; ++i) {
                for(int j = 1; j <= 4; ++j) {
                    xx[j] = x[p[j]];
                    yy[j] = y[p[j]];
                }
                ll d = dis[i];
                xx[2] -= d, xx[3] -= d;
                yy[3] -= d, yy[4] -= d;
                sort(xx + 1, xx + 5);
                sort(yy + 1, yy + 5);
                ll cnt = 0;
                for(int i = 1; i <= 4; ++i) {
                    cnt += abs(xx[i] - xx[2]);
                    cnt += abs(yy[i] - yy[2]);
                }
                ans = min(ans, cnt);
            }
        } while(next_permutation(p + 1, p + 5));
        printf("%lld\n", ans);
    }
    return 0;
}

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
"educational codeforces round 103 (rated for div. 2)"是一个Codeforces平台上的教育性比赛,专为2级选手设计评级。以下是有关该比赛的回答。 "educational codeforces round 103 (rated for div. 2)"是一场Codeforces平台上的教育性比赛。Codeforces是一个为程序员提供竞赛和评级的在线平台。这场比赛是专为2级选手设计的,这意味着它适合那些在算法和数据结构方面已经积累了一定经验的选手参与。 与其他Codeforces比赛一样,这场比赛将由多个问题组成,选手需要根据给定的问题描述和测试用例,编写程序来解决这些问题。比赛的时限通常有两到三个小时,选手需要在规定的时间内提交他们的解答。他们的程序将在Codeforces的在线评测系统上运行,并根据程序的正确性和效率进行评分。 该比赛被称为"educational",意味着比赛的目的是教育性的,而不是针对专业的竞争性。这种教育性比赛为选手提供了一个学习和提高他们编程技能的机会。即使选手没有在比赛中获得很高的排名,他们也可以从其他选手的解决方案中学习,并通过参与讨论获得更多的知识。 参加"educational codeforces round 103 (rated for div. 2)"对于2级选手来说是很有意义的。他们可以通过解决难度适中的问题来测试和巩固他们的算法和编程技巧。另外,这种比赛对于提高解决问题能力,锻炼思维和提高团队合作能力也是非常有帮助的。 总的来说,"educational codeforces round 103 (rated for div. 2)"是一场为2级选手设计的教育性比赛,旨在提高他们的编程技能和算法能力。参与这样的比赛可以为选手提供学习和进步的机会,同时也促进了编程社区的交流与合作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值