Codeforces Round #258 (Div. 2)

来源:互联网 发布:java throws用法 编辑:程序博客网 时间:2024/04/29 20:49

Codeforces Round #258 (Div. 2)

题目链接

A:交叉点个数为min(n, m),所以直接判断min(n, m)的奇偶性即可

B:多开一个数组,保存重排后的序列,然后把两个序列从左边往右和从右边往左,推到都不相同的位置,然后在不相同的一段上,头尾比较判断相不相同即可

C:在纸上画一画很容易看出分4种情况讨论,分别是a > b > c, a < b < c, a > b < c, a < b > c
4种情况有一种符合条件即可

D:很容易看出,字符串中只要首尾相同,就是回文,那么对于奇数的长度,只要选选首尾都是奇数位置或都是偶数位置即可,对于偶数长度,就选首尾寄偶性不同的长度即可,那么可以先预处理出奇数位置的a有多少个,偶数位置的a有多少个,奇数位置的b有多少个,偶数位置的b有多少个,那么奇数长度为C(奇a, 2) + C(奇b, 2) + C(偶a, 2) + C(偶b, 2) + len(长度为1的也是回文),偶数长度为奇a偶a + 偶a 奇b

E:用容斥原理搞,中间要求大组合数,不过由于推出来的公式中C(n, m)的m并不会超过20,所以每个值利用逆元直接去计算即可,容斥是这样做:已知n个组成s,不限值个数的话,用隔板法求出情况为C(s + n - 1, n - 1),但是这部分包含了超过了,那么就利用二进制枚举出哪些是超过的,实现把s减去f(i) + 1这样就保证这个位置是超过的,减去这部分后,有多减的在加回来,这就满足了容斥原理的公式,个数为奇数的时候减去,偶数的时候加回

代码:

A:

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;int n, m;int main() {    scanf("%d%d", &n, &m);    if (n > m) swap(n, m);    printf("%s\n", n % 2 ? "Akshat" : "Malvika");    return 0;}

B:

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int N = 100005;int n, a[N], b[N];int main() {    scanf("%d", &n);    for (int i = 0; i < n; i++) {    scanf("%d", &a[i]);    b[i] = a[i];    }    sort(a, a + n);    int l = 0, r = n - 1;    while (l <= n - 1 && a[l] == b[l]) {    l++;    }    while (r >= 0 && a[r] == b[r]) {    r--;    }    if (l >= r) {    printf("yes\n");    printf("1 1\n");    }    else {    int flag = 1;    int aa = l, bb = r;    for (int i = l; i <= r; i++) {        if (a[i] != b[r - i + l]) {        flag = 0;        break;        }    }    if (flag) {        printf("yes\n");        printf("%d %d\n", aa + 1, bb + 1);    }    else printf("no\n");    }    return 0;}

C:

#include <cstdio>#include <cstring>#include <cstdlib>#include <algorithm>using namespace std;typedef long long ll;ll t, n, k, d1, d2;bool j1(ll n, ll k, ll d1, ll d2) {    if (d1 + d2 + d2 > k) return false;    ll sum = d1 + d2 + d2 + n - k;    if (sum % 3 == 0 && sum / 3 >= d1 + d2) return true;    return false;}bool j2(ll n, ll k, ll d1, ll d2) {    if (d1 + d1 + d2 > k) return false;    ll sum = d1 + d1 + d2 + n - k;    if (sum % 3 == 0 && sum / 3 >= d1 + d2) return true;    return false;}bool j3(ll n, ll k, ll d1, ll d2) {    if (d1 + d2 > k) return false;    ll sum = d1 + d2 + n - k;    ll Max = max(d1, d2);    if (sum % 3 == 0 && sum / 3 >= Max) return true;    return false;}bool j4(ll n, ll k, ll d1, ll d2) {    ll Min = min(d1, d2);    ll Max = max(d1, d2);    ll sum = 2 * abs(d1 - d2) + Min + n - k;    if (2 * abs(d1 - d2) + Min > k) return false;    if (sum % 3 == 0 && sum / 3 >= Max) return true;    return false;}bool judge(ll n, ll k, ll d1, ll d2) {    if (n % 3) return false;    if (j1(n, k, d1, d2)) return true;    if (j2(n, k, d1, d2)) return true;    if (j3(n, k, d1, d2)) return true;    if (j4(n, k, d1, d2)) return true;    return false;}int main() {    scanf("%lld", &t);    while (t--) {    scanf("%lld%lld%lld%lld", &n, &k, &d1, &d2);    if (judge(n, k, d1, d2)) printf("yes\n");    else printf("no\n");    }    return 0;}

D:

#include <cstdio>#include <cstring>const int N = 100005;char str[N];long long ja, jb, oa, ob;long long ansj, anso;int main() {    scanf("%s", str + 1);    int len = strlen(str + 1);    for (int i = 1; i <= len; i++) {    if (i % 2 && str[i] == 'a') ja++;    if (i % 2 && str[i] == 'b') jb++;    if (i % 2 == 0 && str[i] == 'a') oa++;    if (i % 2 == 0 && str[i] == 'b') ob++;    }    ansj = ja * (ja - 1) / 2 + jb * (jb - 1) / 2 + oa * (oa - 1) / 2 + ob * (ob - 1) / 2;    ansj += len;    anso = ja * oa + jb * ob;    printf("%lld %lld\n", anso, ansj);        return 0;}

E:

#include <stdio.h>#include <string.h>#include <algorithm>using namespace std;const long long MOD = 1000000007;const int N = 25;long long n, s, f[N];long long pow(long long x, long long k) {    long long ans = 1;    while (k) {if (k&1) ans = ans * x % MOD;x = x * x % MOD;k >>= 1;    }    return ans;}long long C(long long n, long long m) {    if (m > n) return 0;    m = min(m, n - m);    long long zi = 1, mu = 1;    for (long long i = 0; i < m; i++) {zi = zi * (n - i) % MOD;mu = mu * (i + 1) % MOD;    }    return zi * pow(mu, MOD - 2) % MOD;}long long Lucas(long long n, long long m, long long p) {    if (m == 0) return 1;    return C(n % p, m % p) * Lucas(n / p, m / p, p) % p;}int bitcount(long long x) {    return x == 0 ? 0 : bitcount(x / 2) + (x&1);}int main() {    scanf("%lld%lld", &n, &s);    for (int i = 0; i < n; i++)scanf("%lld", &f[i]);    long long maxs = (1<<n);    long long ans = 0;    for (int i = 0; i < maxs; i++) {long long sum = s;for (int j = 0; j < n; j++) {    if (i&(1<<j)) {sum -= (f[j] + 1);    }    if (sum < 0) break;}if (sum < 0) continue;int tmp = bitcount(i);if (tmp&1) ans -= Lucas(sum + n - 1, n - 1, MOD);else ans += Lucas(sum + n - 1, n - 1, MOD);    }    ans = (ans % MOD + MOD) % MOD;    printf("%lld\n", ans);    return 0;}


1 0
原创粉丝点击