SDUT 2021 Summer Individual Contest - 2(for 20)(补题)

Posted 佐鼬Jun

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SDUT 2021 Summer Individual Contest - 2(for 20)(补题)相关的知识,希望对你有一定的参考价值。

B - Binary Strings

Felipe has a binary string A of length n (1 ≤ n ≤ 5000) which he wants to transform into string B (of length n as well) using a series of operations. He can use the following operations:

  • Operation 1: He can move the last element of A to the front. For example, 01001 would become 10100.

  • Operation 2: He can take any two consecutive elements and flip them. A flip turns a 1 into a 0 and a 0 into a 1. For example, if he applies this operation to the first two elements of 10100, it would become 01100.

Felipe actually doesn’t like operation 2, so he wants to use it as few times as possible. Given A and B find the minimum number of operations type 2 needed to transform A into B, or say if it’s impossible.

Input
Input consist of two lines with binary strings A and B, respectively.

It is guaranteed that both strings have the same length.

Output
Print one single line with the minimum number of operations type 2 needed to transform A into B. or  - 1 if it’s impossible to do so.

Examples
Input

01001
01010
Output
0
Input
11111
00000
Output
-1
Input
001010
100001
Output
1
题意: 有两个仅有‘0’‘1’组成的字符串s1和s2,有两种操作,要么把s1的最后一个单字符放在第一个单字符的位置,要么就选择相邻的单字符进行转换(0和1之间的转换),问最少几步第二个操作,就能把s1转变成说s2,如果不能就输出“-1”
思路:
1. 每次进行第一个操作(最多n次,就变回来了),在通过第二个操作,从前往后扫一遍,一旦不匹配就反转,取最小值
2. 第一个操作无法考虑到‘01010’‘11011’这种转变样例,因为他不会同时操作首位和末尾的字符,可以把先把最后一个放前面,在进行第二个操作,再进行第一个操作恢复原位(实际代码上,就直接把首末字符反转就可以)

#include <bits/stdc++.h>
using namespace std;
const int N = 1e4 + 10;
#define inf 0x3f3f3f3f
char s1[N], s2[N];
char s[N];
char s3[N];
int main() {
    scanf("%s%s", s1, s2);
    int len = strlen(s1);
    int ans = inf;
    int res;
    strcpy(s, s1);
    for (int k = 0; k <= len; k++) {
        res = 0;
        char x = s[len - 1];
        for (int i = len - 2; i >= 0; i--) {
            s[i + 1] = s[i];
        }
        s[0] = x;
        strcpy(s1, s);
        strcpy(s3, s);
        for (int i = 0; i < len; i++) {
            if (i == len - 1) {
                if (s1[i] != s2[i]) {
                    res = inf;
                }
            }
            if (s1[i] == s2[i])
                continue;
            else if (s1[i] == '0' && s2[i] == '1') {
                res++;
                s1[i] = '1';
                if (s1[i + 1] == '0')
                    s1[i + 1] = '1';
                else
                    s1[i + 1] = '0';
            } else if (s1[i] == '1' && s2[i] == '0') {
                res++;
                s1[i] = '0';
                if (s1[i + 1] == '0')
                    s1[i + 1] = '1';
                else
                    s1[i + 1] = '0';
            }
        }
        int dex = 1;
        if(s3[0]=='1') s3[0]='0';
        else s3[0]='1';
        if(s3[len-1]=='1') s3[len-1]='0';
        else s3[len-1]='1';
        for (int i = 0; i < len; i++) {
            if (i == len - 1) {
                if (s3[i] != s2[i]) {
                    dex = inf;
                }
            }
            if (s3[i] == s2[i])
                continue;
            else if (s3[i] == '0' && s2[i] == '1') {
                dex++;
                s3[i] = '1';
                if (s3[i + 1] == '0')
                    s3[i + 1] = '1';
                else
                    s3[i + 1] = '0';
            } else if (s3[i] == '1' && s2[i] == '0') {
                dex++;
                s3[i] = '0';
                if (s3[i + 1] == '0')
                    s3[i + 1] = '1';
                else
                    s3[i + 1] = '0';
            }
        }
        ans = min({res, ans, dex});
    }
    if (ans == inf)
        puts("-1");
    else
        printf("%d\\n", ans);
    return 0;
}

E - Equilateral Triangles


题意: 两个点之间的连线如果经过了其他点,那么这对点就是我们要的,问这个三角形中有多少对这样的点
思路: 把等边三角形转换成直角三角形(代码中不用体现),然后枚举所有的点,如果两个点的水平和竖直距离(曼哈顿距离)的最大公约数>1,那么就是我们要的一对点,因为最大公约数不是1,说明这两个数有共同的约数,约去这个数后,他们会形成一个对新数,一开始的数和这对新数,斜率是一样的,所以一定是在同一条直线上的,所以这对数是我们要的。

#include <bits/stdc++.h>
using namespace std;
#define x first
#define y second
typedef pair<int, int> PII;
vector<PII> a;
int n, res;
int main() {
    cin >> n;
    for (int i = 0; i <= n; i++) {
        for (int j = 0; j <= n - i; j++) {
            a.push_back({i, j});
        }
    }
    for (int i = 0; i < a.size(); i++) {
        for (int j = i + 1; j < a.size(); j++) {
            int u = a[i].x - a[j].x;
            int v = a[i].y - a[j].y;
            int t = __gcd(abs(u), abs(v));
            if (t > 1) {
                res++;
            }
        }
    }
    cout << res << endl;
    return 0;
}

To be continued
如果你有任何建议或者批评和补充,请留言指出,不胜感激

以上是关于SDUT 2021 Summer Individual Contest - 2(for 20)(补题)的主要内容,如果未能解决你的问题,请参考以下文章

SDUT 2021 Summer Individual Contest - 7(补题)

SDUT 2021 summer team contest 1st(for 20)(补题)

SDUT 2021 Spring Individual Contest(for 20) - 18(补题)

SDUT 2021 Spring Individual Contest(for 20) - 14(补题)

SDUT 2021 Spring Individual Contest(for 20) - 1补题

SDUT 2021 Winter Individual Contest - N(B-Derangement)