Codeforces Round #640 (Div. 4)解题报告

这个div4还是比较基础的,比赛的时候写了4题就睡觉去了,早上起来花了几十分钟把剩余的题补了,总的来说还是比较适合初学者的。

A. Sum of Round Numbers

题目就不粘贴了。
就是把一个数 n n n表示成round数,如 9876 9876 9876,输出 9000 , 800 , 70 , 6 9000,800,70,6 9000,800,70,6 5009 5009 5009,输出 5000 , 9 5000,9 5000,9,例子一看就知道怎么搞了。

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
typedef long long ll;
const int N = 1e5 + 10;
const int INF = 0x3f3f3f3f;
int max(int a, int b) { return a > b ? a : b; }
int min(int a, int b) { return a > b ? b : a; }
const double eps = 1e-7;
#define endl '\n'
#define pb(a) push_back(a)
#define ALL(x) x.begin(), x.end()
int mypow(int x, int n) {
    for (int i = 1; i <= n; ++i) x *= 10;
    return x;
}
int main() {
    // ios::sync_with_stdio(false);
    int t;
    scanf("%d", &t);
    while (t--) {
        string s;
        cin >> s;
        int n = s.size() - 1;
        vector<int> ans;
        for (int i = 0; i < s.size(); ++i) {
            if (s[i] != '0') {
                ans.pb(mypow(s[i] - '0', n));
            }
            n--;
        }
        printf("%d\n", ans.size());
        for (auto it : ans) printf("%d ", it);
        printf("\n");
    }
    return 0;
}

B. Same Parity Summands

B题有点恶心,写了很多的判断语句,首先需要知道

  • 奇数+奇数=偶数
  • 偶数+偶数=偶数
  • 奇数+偶数=奇数

然后看题目你最终要表示成什么数的和,如果是奇数,那么就是 n = ∑ 1 k − 1 1 + ( n − k + 1 ) n = \sum_{1}^{k-1} 1+(n-k+1) n=1k11+(nk+1,如果表示成偶数,那么就是 n = ∑ 1 k − 1 2 + n − 2 × ( k − 1 ) n=\sum_{1}^{k-1}2+n-2 \times (k-1) n=1k12+n2×(k1),如果表示不出来就是NO

还有一些特殊判断的,如果n=k,那么直接输出 k k k 1 1 1,如果k是偶数并且n是奇数,那直接NO

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
typedef long long ll;
const int N = 1e5 + 10;
const int INF = 0x3f3f3f3f;
int max(int a, int b) { return a > b ? a : b; }
int min(int a, int b) { return a > b ? b : a; }
const double eps = 1e-7;
#define endl '\n'
#define pb(a) push_back(a)
#define ALL(x) x.begin(), x.end()

int main() {
    // ios::sync_with_stdio(false);
    int t;
    scanf("%d", &t);
    while (t--) {
        ll n;
        int k;
        scanf("%lld%d", &n, &k);
        if (k & 1 == 0 && n % 2 == 1) {
            puts("NO");
            continue;
        }
        if (n == k) {
            puts("YES");
            for (int i = 1; i <= k; ++i) printf("1 ");
            puts("");
            continue;
        }
        if (k & 1) {
            if (n & 1 && n - k + 1 >= 1) {
                printf("YES\n");
                for (int i = 1; i <= k - 1; ++i) printf("1 ");
                printf("%lld\n", n - k + 1);
            } else if (n % 2 == 0 && n - 2 * (k - 1) >= 2) {
                printf("YES\n");
                for (int i = 1; i <= k - 1; ++i) printf("2 ");
                printf("%lld\n", n - 2 * (k - 1));
            } else {
                printf("NO\n");
            }
        } else {
            if (n % 2 == 0 && n - k + 1 >= 2) {
                printf("YES\n");
                for (int i = 1; i <= k - 1; ++i) printf("1 ");
                printf("%lld\n", n - k + 1);
            } else if (n % 2 == 0 && n - 2 * (k - 1) >= 2) {
                printf("YES\n");
                for (int i = 1; i <= k - 1; ++i) printf("2 ");
                printf("%lld\n", n - 2 * (k - 1));
            } else {
                printf("NO\n");
            }
        }
    }
    return 0;
}

C. K-th Not Divisible by n

C题找规律题,写两个例子就知道了。

n=3
数:   1 2 4 5 7 8 10 11 13
下标:  1 2 3 4 5 6  7  8  9
将数与下标相减: 
       0  0 1 1 2 2 3 3 4...

n=4
1 2 3 5 6 7 9 10 11 13 14 15
1 2 3 4 5 6 7 8  9  10 11 12
0 0 0 1 1 1 2 2  2  3  3  3...

可以发现是有规律的,应该看得出来,我们设数与下标相减为 p p p,那么第 k k k个数就是 p + k p+k p+k,所以只要算出 p p p即可。
易发现 n = 3 n=3 n=3时是以 2 2 2为周期的, n = 4 n=4 n=4时是以 3 3 3为周期的,所以每一组都是以 n − 1 n-1 n1为周期的,那么 p = ⌈ k n − 1 ⌉ − 1 p=\left \lceil \frac{k}{n-1} \right \rceil -1 p=n1k1,ok!

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
typedef long long ll;
const int N = 1e5 + 10;
const int INF = 0x3f3f3f3f;
int max(int a, int b) { return a > b ? a : b; }
int min(int a, int b) { return a > b ? b : a; }
const double eps = 1e-7;
#define endl '\n'
#define pb(a) push_back(a)
#define ALL(x) x.begin(), x.end()

int main() {
    // ios::sync_with_stdio(false);
    int t;
    scanf("%d", &t);
    while (t--) {
        ll n, k;
        scanf("%lld%lld", &n, &k);
        ll p;
        if (k % (n - 1) == 0)
            p = k / (n - 1);
        else
            p = k / (n - 1) + 1;
        printf("%lld\n", p - 1 + k);
    }
    return 0;
}

D. Alice, Bob and Candies

模拟题,题目看懂即可。

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
typedef long long ll;
const int N = 1e5 + 10;
const int INF = 0x3f3f3f3f;
int max(int a, int b) { return a > b ? a : b; }
int min(int a, int b) { return a > b ? b : a; }
const double eps = 1e-7;
#define endl '\n'
#define pb(a) push_back(a)
#define ALL(x) x.begin(), x.end()
int a[1010];
int main() {
    // ios::sync_with_stdio(false);
    int t;
    scanf("%d", &t);
    while (t--) {
        int n;
        scanf("%d", &n);
        for (int i = 1; i <= n; ++i) {
            scanf("%d", &a[i]);
        }
        int sa = 0, sb = 0;
        int pa = 1, pb = n;
        int cnt = 0;
        int pre = 0;
        while (pa <= pb) {
            int tmp = 0;
            while (tmp <= pre && pa <= pb) {
                tmp += a[pa++];
            }
            pre = tmp;
            sa += tmp;
            cnt++;
            if (pa > pb) break;

            int tmp2 = 0;
            while (tmp2 <= pre && pb >= pa) {
                tmp2 += a[pb--];
            }
            pre = tmp2;
            sb += tmp2;
            cnt++;
        }
        printf("%d %d %d\n", cnt, sa, sb);
    }
    return 0;
}

E. Special Elements

E题用set会mle,用map也mle,看来stl是用空间换时间的,这题用数组标记就行了。

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
typedef long long ll;
const int N = 1e7;
const int INF = 0x3f3f3f3f;
int max(int a, int b) { return a > b ? a : b; }
int min(int a, int b) { return a > b ? b : a; }
const double eps = 1e-7;
#define endl '\n'
#define pb(a) push_back(a)
#define ALL(x) x.begin(), x.end()
int n, a[8002];
int f[8002];
int main() {
    // ios::sync_with_stdio(false);
    int t;
    scanf("%d", &t);
    while (t--) {
        scanf("%d", &n);
        for (int i = 1; i <= n; ++i) {
            scanf("%d", a + i);
            f[a[i]]++;
        }
        int cnt = 0;
        for (int i = 1; i <= n - 1; ++i) {
            int sum = a[i];
            for (int j = i + 1; j <= n; ++j) {
                sum += a[j];
                if (sum > n) break;
                if (f[sum]) {
                    cnt += f[sum];
                    f[sum] = 0;
                }
            }
        }
        for (int i = 1; i <= n; ++i) {
            f[i] = 0;
        }
        printf("%d\n", cnt);
    }
    return 0;
}

F. Binary String Reconstruction

构造题,细节有点多。
下面是我的构造方法:
不考虑具体细节,首先先把 n 0 n_0 n0消掉, 000 ⋯ 0 ⏟ n 0 + 1 \begin{matrix} \underbrace{ 000\cdots0 } \\ n_0+1 \end{matrix} 0000n0+1,然后在两侧加入 1 1 1,这时 n 1 = n 1 − 2 n_1=n_1-2 n1=n12,然后再在一侧加 n 2 n_2 n2 1 1 1即可。
但是有很多细节。
因为要频繁头插尾插,可以用deque完成。

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
typedef long long ll;
const int N = 1e5 + 10;
const int INF = 0x3f3f3f3f;
int max(int a, int b) { return a > b ? a : b; }
int min(int a, int b) { return a > b ? b : a; }
const double eps = 1e-7;
#define endl '\n'
#define pb(a) push_back(a)
#define ALL(x) x.begin(), x.end()
int n0, n1, n2;

void solve() {
    deque<char> d;
    for (int i = 1; i <= n0; ++i) d.push_back('0');
    if (n0) d.push_back('0');  //细节1
    if (!n0 && n1) d.push_back('0'); //细节2
    int f = 0;
    if (n1 >= 1) d.push_front('1'), n1--, f = 1;
    if (n1 >= 1) d.push_back('1'), n1--;
    if (!f && n2) d.push_front('1'); //细节3
    for (int i = 1; i <= n2; ++i) d.push_front('1');
    n2 = 0;
    if (n1) {
        while (n1 >= 2) {
            d.push_front('0');
            d.push_front('1');
            n1 -= 2;
        }
        if (n1 == 1) {
            d.push_back('0');
        }
        n1 = 0;
    }
    for (auto it : d) {
        printf("%c", it);
    }
    printf("\n");
}

int main() {
    // ios::sync_with_stdio(false);
    int t;
    scanf("%d", &t);
    while (t--) {
        scanf("%d%d%d", &n0, &n1, &n2);
        solve();
    }
    return 0;
}

G. Special Permutation

一道可以算是经典dfs题,生成这种有条件的序列。还是蛮水的。

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
typedef long long ll;
const int N = 1e5 + 10;
const int INF = 0x3f3f3f3f;
int max(int a, int b) { return a > b ? a : b; }
int min(int a, int b) { return a > b ? b : a; }
const double eps = 1e-7;
#define endl '\n'
#define pb(a) push_back(a)
#define ALL(x) x.begin(), x.end()
int n;
int ans[1010];
bool vis[1010];
bool f;
void dfs(int pre, int k) {
    if (k == n + 1) {
        f = true;
        return;
    }
    for (int i = 1; i <= n; ++i) {
        if (k == 1 && !vis[i]) {
            vis[i] = 1;
            ans[k] = i;
            dfs(i, k + 1);
            if (f) return;
            vis[i] = 0;
        } else {
            if (!vis[i] && abs(i - pre) >= 2 && abs(pre - i) <= 4) {
                vis[i] = 1;
                ans[k] = i;
                dfs(i, k + 1);
                if (f) return;
                vis[i] = 0;
            }
        }
    }
}
int main() {
    // ios::sync_with_stdio(false);
    int t;
    scanf("%d", &t);
    while (t--) {
        scanf("%d", &n);
        memset(vis, 0, sizeof(vis));
        memset(ans, 0, sizeof(ans));
        f = 0;
        dfs(0, 1);
        int cnt = 0;

        for (int i = 1; i <= n; ++i) {
            if (ans[i]) cnt++;
        }
        if (cnt == n) {
            for (int i = 1; i <= n; ++i) {
                printf("%d ", ans[i]);
            }
            printf("\n");
        } else {
            printf("-1\n");
        }
    }
    return 0;
}

你可能感兴趣的:(cf)