Contest CF719 div3 补题

[TOC]

CF719 div3 补题

https://codeforces.com/contest/1520

A

题目大意:看字串中是否有重复出现的,连续一段出现可以,中间隔着其他的,然后再次出现就不行了。

思路:用map来维护前面所出现过的所有字符,看是否存在

#include <bits/stdc++.h>
using namespace std;
int t, n;
#include <map>
map<char, int> m;
char s[55];

int main() {
    scanf("%d", &t);
    while (t--) {
        int flag = 0;
        m.clear();
        scanf("%d%s", &n, s);
        m[s[0]] = 1;
        for (int i = 1; i < strlen(s); ++i) {
            if (s[i] != s[i - 1] && m.count(s[i])) flag = 1;
            else m[s[i]] = 1;
        }
        if (flag) printf("NO\n");
        else printf("YES\n");
    }
    return 0;
}

B

题目大意:找1~n范围中,所有数都相同的数(1 2 88 444是,101 67 1239不是)

思路:直接打表,然后遍历,看看第多少个比他大,此时的索引就是个数

注意:一定要看数据范围,这个题的数据范围是1e9,就不可以用int了,要用longlong

#include <bits/stdc++.h>
using namespace std;
long long t, n;
long long a[82] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 22, 33, 44, 55, 66, 77, 88, 99, 111, 222, 333, 444, 555, 666, 777,
                   888, 999, 1111, 2222, 3333, 4444, 5555, 6666, 7777, 8888, 9999, 11111, 22222, 33333, 44444, 55555,
                   66666, 77777, 88888, 99999, 111111, 222222, 333333, 444444, 555555, 666666, 777777, 888888, 999999,
                   1111111, 2222222, 3333333, 4444444, 5555555, 6666666, 7777777, 8888888, 9999999, 11111111, 22222222,
                   33333333, 44444444, 55555555, 66666666, 77777777, 88888888, 99999999, 111111111, 222222222,
                   333333333, 444444444, 555555555, 666666666, 777777777, 888888888, 999999999, 1111111111};

int main() {
    scanf("%lld", &t);
    while (t--) {
        scanf("%lld", &n);
        for (int i = 0; i < 82; ++i)
            if (n < a[i]) {
                printf("%d\n", i);
                break;
            }
    }
    return 0;
}

C

题目大意:填矩阵,相邻的上下左右的差值不能为1。

思路:利用横纵坐标的和呈现斜对角线的奇-偶-奇-偶,然后沿对角线网上开始排布即可。

#include <bits/stdc++.h>
using namespace std;
const int maxn = 105;
int t, n, ans[maxn][maxn], idx;

int main() {
    scanf("%d", &t);
    while (t--) {
        idx = 0;scanf("%d", &n);
        if (n == 2) {printf("-1\n");continue;}
        for (int b = 0; b < 2; ++b)
            for (int i = 0; i < n; ++i)
                for (int j = 0; j < n; ++j)
                    if ((i+j)%2 == b) ans[i][j] = ++idx;
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < n; ++j) {
                printf("%d ", ans[i][j]);
            }
            printf("\n");
        }
    }
    return 0;
}

D

题目大意:找A-B = A_idx-B_idx

思路一:直接O(n^2)暴力,2e5数据,tle

思路二:用两个指针,实质上还是思路一

思路三:找相同的等差的,然后选为同一集合,然后从每个集合中挑出两个组合起来(注意这里是确定挑两个的组合数,所以没必要用combo公式,不然会tle)

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll t, n, tem, ans;
#include <map>
map<ll, ll> m;

int main() {
    scanf("%lld", &t);
    while (t--) {
        ans = 0;m.clear();
        scanf("%lld", &n);
        for (int i = 1; i <= n; ++i) {
            scanf("%lld", &tem);
            m[tem-i]++;
        }
        for (auto [k, v] : m) ans += v*(v-1)/2; // 遍历map利用[k, v]遍历的方法是在C++17中的方法,C++11/13都没有的
        printf("%lld\n", ans);
    }
    return 0;
}
Posted on Feb 4, 2020