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
如果你有任何建议或者批评和补充,请留言指出,不胜感激

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值