Codeforces Round #753 (Div. 3)

Posted zhy-cx

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #753 (Div. 3)相关的知识,希望对你有一定的参考价值。

Codeforces Round #753 (Div. 3)

A. Linear Keyboard

思路分析:

  • 无语了,题目总是读不顺,看到output那个minimal我还以为是把手放到一个单词上,看需要多少time来完成敲出字符串。
  • 写完一看,答案不对劲,然后发现这题其实就是把字母表重新排一下,然后求两个字母间的距离之差的绝对值。

代码

#include <bits/stdc++.h>
using namespace std;
map<char, int> mp;
int main()
{
        ios::sync_with_stdio(0);
        cin.tie(0);
        cout.tie(0);
        int t;
        cin >> t;
        while (t--)
        {
                string s;
                cin >> s;
                for (int i = 0; i < s.size(); i++)
                {
                        mp[s[i]] = i + 1;
                }
                string t;
                cin >> t;
                int ans = 0;
                for (int i = 1; i < t.size(); i++)
                {
                        ans += abs(mp[t[i]] - mp[t[i - 1]]);
                }
                cout << ans << endl;
        }
        return 0;
}

B. Odd Grasshopper

思路分析:

  • 这个题目其实是找规律题,并且只和一开始给你的第一个值的奇偶有关。
  • 如果给你的是偶数,那么就是-,+,+,-,-,+,+,-,-......
  • 如果给你的是奇数,那么就是+,-,-,+,+,-,-,+,+......
  • 我们可以看出除了第一个之外,后面每四个加起来都有规律,偶数时是-4,奇数时是4......
  • 然后就是分析剩下来不能成为一组的,那么找一下规律即可。

代码

#include <bits/stdc++.h>
using namespace std;
#define ll long long
int main()
{
        ios::sync_with_stdio(0);
        cin.tie(0);
        cout.tie(0);
        int t;
        cin >> t;
        while (t--)
        {
                ll x, n;
                cin >> x >> n;
                if (n == 0)
                {
                        cout << x << endl;
                }
                else
                {
                        if (x % 2 == 0)
                        {
                                x--;
                                n--;
                                x = x + n / 4 * (-4);
                                if (n % 4 == 0)
                                {
                                        cout << x << endl;
                                }
                                else if (n % 4 == 1)
                                {
                                        x += (n + 1);
                                        cout << x << endl;
                                }
                                else if (n % 4 == 2)
                                {
                                        x += (2 * n + 1);
                                        cout << x << endl;
                                }
                                else if (n % 4 == 3)
                                {
                                        x += (n - 2);
                                        cout << x << endl;
                                }
                        }
                        else
                        {
                                x++;
                                n--;
                                x = x + n / 4 * 4;
                                if (n % 4 == 0)
                                {
                                        cout << x << endl;
                                }
                                else if (n % 4 == 1)
                                {
                                        x -= (n + 1);
                                        cout << x << endl;
                                }
                                else if (n % 4 == 2)
                                {
                                        x -= (2 * n + 1);
                                        cout << x << endl;
                                }
                                else if (n % 4 == 3)
                                {
                                        x -= (n - 2);
                                        cout << x << endl;
                                }
                        }
                }
        }
        return 0;
}

C. Minimum Extraction

思路分析:

  • 我们要求的是在删减过程中数组最小值的最大值。
  • 首先我们肯定是要排序的,然后依次求最小值出来,可以肯定的是我们从最小的开始选的话,在这个过程中每个数都会减去之前删的那个数,在删到某个数前,它必然会变成他和前面那个数的差值,因为,我们从第一个开始,到删到它前面一个数时,这两个数的差值一直没变,所以最大的最小值其实就是排序后的数组的两两相邻数的差值的最大值。

代码

#include <bits/stdc++.h>
using namespace std;

const int maxn = 2e5 + 10;
int a[maxn];

int main()
{
        ios::sync_with_stdio(0);
        cin.tie(0);
        cout.tie(0);
        int t;
        cin >> t;
        while (t--)
        {
                int n;
                cin >> n;
                for (int i = 1; i <= n; i++)
                {
                        cin >> a[i];
                }
                sort(a + 1, a + 1 + n);
                int ans = -1000000001;
                for (int i = 1; i <= n; i++)
                {
                        ans = max(ans, a[i] - a[i - 1]);
                }
                cout << ans << endl;
        }
        return 0;
}

D. Blue-Red Permutation

思路分析:

  • 这个题目其实就是贪心,我们这样想,先把blue颜色的num放到前面,因为它们只能变小或者不变而不能变大,我们要得到的是一个\\(1 - n\\)的排列,也就是说得到的数组的值中\\(1 - n\\)这些数必然出现并且一个只出现一次。
  • 那么我们把可以变小的num先放到前面(同颜色的按值大小排序,显然值越小越排到前面)。
  • 然后就是定义一个tmp来表示当前要造的数,如果我们遍历数组时,它比tmp大而且它只能变大,那肯定就是不对的、如果它比tmp小并且它只能变小,也是不对的。

代码

#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 10;
struct node
{
        int val;
        char ch;
} a[maxn];

bool cmp(node a, node b)
{
        if (a.ch != b.ch)
                return a.ch < b.ch;
        return a.val < b.val;
}
int main()
{
        ios::sync_with_stdio(0);
        cin.tie(0);
        cout.tie(0);
        int t;
        cin >> t;
        while (t--)
        {
                int n;
                cin >> n;
                for (int i = 1; i <= n; i++)
                {
                        cin >> a[i].val;
                }
                for (int i = 1; i <= n; i++)
                {
                        cin >> a[i].ch;
                }
                sort(a + 1, a + 1 + n, cmp);
                bool flag = 1;
                int tmp = 1;
                for (int i = 1; i <= n; i++)
                {
                        if (a[i].val < tmp && a[i].ch == \'B\')
                        {
                                flag = 0;
                                break;
                        }
                        else if (a[i].val > tmp && a[i].ch == \'R\')
                        {
                                flag = 0;
                                break;
                        }
                        else
                        {
                                tmp++;
                        }
                }
                if (flag)
                {
                        cout << "YES" << endl;
                }
                else
                {
                        cout << "NO" << endl;
                }
        }
        return 0;
}

E. Robot on the Board 1

思路分析:

  • 这题是看dalao代码学的,首先我们可以这样想,我们拿出四根线,分别放置在矩阵上下左右外,也就是放在外面,然后每次我们都更新一下上下左右边界,记录边界。
  • 然后就是什么时候输出,第一种情况当然是现在左右(上下)边界相差大于\\(2\\)(那么我们只需要选上左边界相夹的那一块的坐标即可。),第二种情况就是至少有两个边界(l和r 或者 u和d)相差为\\(1\\)了,那么这个时候我们不能再更新答案了,因为那两个边界中间已经没有块可选了,所以只要输出上一次的答案即可。

代码

#include <bits/stdc++.h>
using namespace std;

int main()
{
        ios::sync_with_stdio(0);
        cin.tie(0);
        cout.tie(0);
        int t;
        cin >> t;
        while (t--)
        {
                int n, m;
                cin >> n >> m;
                string s;
                cin >> s;
                pair<int, int> a;
                a = {1, 1};
                bool flag = 0;
                int l = 0, r = m + 1, u = 0, d = n + 1;
                int suml = 0, sumr = 0, sumu = 0, sumd = 0;
                for (int i = 0; i < s.size(); i++)
                {
                        if (s[i] == \'R\')
                        {
                                sumr++;
                        }
                        else if (s[i] == \'L\')
                        {
                                suml++;
                        }
                        else if (s[i] == \'U\')
                        {
                                sumu++;
                        }
                        else if (s[i] == \'D\')
                        {
                                sumd++;
                        }
                        l = max(l, suml - sumr);
                        r = min(r, m + 1 - (sumr - suml));
                        u = max(u, sumu - sumd);
                        d = min(d, n + 1 - (sumd - sumu));
                        if (l + 1 >= r || u + 1 >= d)
                        {
                                flag = 1;
                                cout << a.first << \' \' << a.second << endl;
                                break;
                        }
                        else
                        {
                                a = {u + 1, l + 1};
                        }
                }
                if (!flag)
                        cout << a.first << " " << a.second << endl;
        }
        return 0;
}

[ACM]Codeforces Round #534 (Div. 2)

一、前言
二、题面

A. Splitting into digits

Vasya has his favourite number n. He wants to split it to some non-zero digits. It means, that he wants to choose some digits d1,d2,…,dk, such that 1≤di≤9 for all i and d1+d2+…+dk=n.

Vasya likes beauty in everything, so he wants to find any solution with the minimal possible number of different digits among d1,d2,…,dk. Help him!

Input
The first line contains a single integer n — the number that Vasya wants to split (1≤n≤1000).

Output
In the first line print one integer k — the number of digits in the partition. Note that k must satisfy the inequality 1≤k≤n. In the next line print k digits d1,d2,…,dk separated by spaces. All digits must satisfy the inequalities 1≤di≤9.

You should find a partition of n in which the number of different digits among d1,d2,…,dk will be minimal possible among all partitions of n into non-zero digits. Among such partitions, it is allowed to find any. It is guaranteed that there exists at least one partition of the number n into digits.

Examples
input
1
output
1
1

input
4
output
2
2 2

input
27
output
3
9 9 9

Note
In the first test, the number 1 can be divided into 1 digit equal to 1.

In the second test, there are 3 partitions of the number 4 into digits in which the number of different digits is 1. This partitions are [1,1,1,1], [2,2] and [4]. Any of these partitions can be found. And, for example, dividing the number 4 to the digits [1,1,2] isn‘t an answer, because it has 2 different digits, that isn‘t the minimum possible number.

题意:尝试用k个数字(0~9)加起来变成n,要求数字种类尽可能少,即能全部用相同的数字时就不用不同的数字。

正解:cf日常无聊题。第一行输出n,第二行输出n个1即可。

代码:略

 

B. Game with string

Two people are playing a game with a string s, consisting of lowercase latin letters.

On a player‘s turn, he should choose two consecutive equal letters in the string and delete them.

For example, if the string is equal to "xaax" than there is only one possible turn: delete "aa", so the string will become "xx". A player not able to make a turn loses.

Your task is to determine which player will win if both play optimally.

Input
The only line contains the string s, consisting of lowercase latin letters (1≤|s|≤100000), where |s| means the length of a string s.

Output
If the first player wins, print "Yes". If the second player wins, print "No".

Examples
input
abacaba

output
No

input
iiq

output
Yes

input
abba

output
No

Note
In the first example the first player is unable to make a turn, so he loses.

In the second example first player turns the string into "q", then second player is unable to move, so he loses.

 

题意:每次从给出的字符串删去两个相连且相同的字符,删去个数为奇数时输出Yes,偶数输出No。

思路:扫描字符串,找到相连的相同字符后,左端点向左,右端点向右进行搜索,直至左右端点不是相同字符,结束,继续扫描,直至字符串末尾。注意,删除子串后应将删除部分的左端和右端相连,以保证后面的扫描的正确性。解决这个问题,我们可以先对字符串进行链标记,对字符进行串联,即对每一个字符标记一个左字符和右字符,初始即其左右的临近字符,在每次操作后可将该标记进行调整。

代码:

 1 #include <bits/stdc++.h>
 2 #define MAXN 100005
 3 
 4 char ch[MAXN];
 5 int len, tot;
 6 
 7 struct node {
 8     char s;
 9     int l, r;
10 } a[MAXN];
11 .
12 int chk(int o) {
13     int l = o, r = o + 1; tot++;
14     while (a[a[l].l].s == a[a[r].r].s && a[a[l].l].s != 00) 
15         l = a[l].l, r = a[r].r, tot++;
16     a[a[r].r].l = a[l].l;
17     return a[r].r;
18 }
19 
20 int main() {
21     scanf("%s", ch + 1), len = strlen(ch + 1);
22     for (int i = 1; i <= len; i++) a[i].s = ch[i], a[i].l = i - 1, a[i].r = i + 1;
23     for (int i = 1; i <= len; i = (a[i].s == a[i + 1].s && a[i].s != 00) ? chk(i) : i + 1);
24     printf(tot % 2 ? "Yes" : "No");
25     return 0;
26 }

 































以上是关于Codeforces Round #753 (Div. 3)的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces Round #753 (Div. 3) ABCD

Codeforces Round #753 (Div. 3) ABCD

Codeforces Round #753 (Div. 3) ABCD

Codeforces Round #753 (Div. 3) A-E

Codeforces Round #753 (Div. 3)(ABCDE)

Codeforces Round #436 E. Fire(背包dp+输出路径)