Codeforces Round #664 (Div. 2)A-D题解

A − B o b o n i u A - Boboniu ABoboniu L i k e s Likes Likes t o to to C o l o r Color Color B a l l s Balls Balls

思路:
可以知道 r , b , g , w r,b,g,w r,b,g,w中的奇数数量不大于1,就可以构造回文序列,若奇数数量大于1,我们只需要一次判断即可,因为修改后的 r , g , b , w r,g,b,w r,g,b,w若可以成功就可以成功,反则它每次修改后每个数都 ±奇数,会形成奇数偶数数量互补的情况,整体奇数和偶数的数量不会改变。

参考代码:

#include <cstdio>
#include <algorithm>
#include <iostream>
#include <vector>
#include <map>
#include <queue>
#include <set>
#include <ctime>
#include <cstring>
#include <cstdlib>
#include <math.h>
using namespace std;
typedef long long ll;
//#define ll long long
const ll N = 2009;
const ll maxn = 1e5 + 20;
const ll mod = 1000000007;
ll inv[maxn], vis[maxn], dis[maxn], head[maxn];
ll fac[maxn], a[maxn], q[maxn], b[N], c[N], pre[maxn];
vector<ll> vec;
//typedef pair<ll, ll> p;
//priority_queue<p, vector<p>, greater<p> > m;
// ll sum[maxn], a[maxn];
ll max(ll a, ll b) { return a > b ? a : b; }
ll min(ll a, ll b) { return a < b ? a : b; }
ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
ll lcm(ll a, ll b) { return a * b / gcd(a, b); }
map<ll, ll> mp;
ll ksm(ll a, ll b)
{
    a %= mod;
    ll ans = 1ll;
    while (b)
    {
        if (b & 1)
            ans = (ans * a) % mod;
        a = (a * a) % mod;
        b >>= 1ll;
    }
    return ans;
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    ll t, n, m, k;
    cin >> t;
    while (t--)
    {
        ll r, g, b, w;
        cin >> r >> g >> b >> w;
        ll ans = 0;
        if (r & 1)
            ans++;
        if (g & 1)
            ans++;
        if (b & 1)
            ans++;
        if (w & 1)
            ans++;
        if (ans <= 1ll)
            cout << "Yes" << endl;
        else
        {
            if (r == 0 || g == 0 || b == 0)
            {
                cout << "No" << endl;
                continue;
            }
            r--, g--, b--, w += 3;
            ans = 0;
            if (r & 1)
                ans++;
            if (g & 1)
                ans++;
            if (b & 1)
                ans++;
            if (w & 1)
                ans++;
            if (ans <= 1)
                cout << "Yes" << endl;
            else
                cout << "No" << endl;
        }
    }
}

B − B o b o n i u B - Boboniu BBoboniu P l a y s Plays Plays C h e s s Chess Chess

思路:
按照题意随意走就行

参考代码:

#include <cstdio>
#include <algorithm>
#include <iostream>
#include <vector>
#include <map>
#include <queue>
#include <set>
#include <ctime>
#include <cstring>
#include <cstdlib>
#include <math.h>
using namespace std;
typedef long long ll;
//#define ll long long
const ll N = 2009;
const ll maxn = 1e5 + 20;
const ll mod = 1000000007;
//ll inv[maxn], vis[maxn], dis[maxn], head[maxn];
ll fac[maxn], a[maxn], q[maxn], b[N], c[N], pre[maxn];
vector<ll> vec;
//typedef pair<ll, ll> p;
//priority_queue<p, vector<p>, greater<p> > m;
// ll sum[maxn], a[maxn];
ll max(ll a, ll b) { return a > b ? a : b; }
ll min(ll a, ll b) { return a < b ? a : b; }
ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
ll lcm(ll a, ll b) { return a * b / gcd(a, b); }
map<ll, ll> mp;
ll ksm(ll a, ll b)
{
    a %= mod;
    ll ans = 1ll;
    while (b)
    {
        if (b & 1)
            ans = (ans * a) % mod;
        a = (a * a) % mod;
        b >>= 1ll;
    }
    return ans;
}
int vis[N][N], n, m;
int dir[4][2] = {0, 1, 1, 0, 0, -1, -1, 0};
void dfs(int x, int y)
{
    cout << x << ' ' << y << endl;
    vis[x][y] = 1;
    for (int i = 0; i < 4; i++)
    {
        int xx = x + dir[i][0], yy = y + dir[i][1];
        if (xx <= 0)
            xx = n;
        if (yy <= 0)
            yy = m;
        if (xx > n)
            xx = 1;
        if (yy > m)
            yy = 1;
        if (!vis[xx][yy])
            dfs(xx, yy);
    }
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    ll t;
    // cin >> t;
    // while (t--)
    // {
    //     memset(vis,0,sizeof vis);
    int x, y;
    cin >> n >> m >> x >> y;
    dfs(x, y);
    // }
}

C − B o b o n i u C - Boboniu CBoboniu a n d and and B i t Bit Bit O p e r a t i o n s Operations Operations

思路:
这题挺巧妙的,根据数据范围, c 1 ∣ c 2 ∣ . . . . c n c1|c2|....cn c1c2....cn的最大可能值为 111111111 111111111 111111111(二进制情况下)十进制为 523 523 523,所以枚举 0 − 523 0-523 0523,令 r e s = c 1 ∣ c 2 ∣ . . . . c n res=c1|c2|....cn res=c1c2....cn,所以 r e s ∣ c i = = r e s res|ci==res resci==res,利用这个条件进行枚举,若 ( a [ i ] (a[i] (a[i]& b [ j ] ) ∣ r e s = = r e s b[j])|res==res b[j])res==res存在一个,则说明 ( a [ i ] (a[i] (a[i]& a [ j ] ) a[j]) a[j])可以成为 c 1 ∣ c 2 ∣ . . . . c n c1|c2|....cn c1c2....cn的一部分,如果没有说明当前的答案是无法形成的,因为是从小到大进行枚举,所以第一个满足条件的,就是最小的。

参考代码:

#include <cstdio>
#include <algorithm>
#include <iostream>
#include <vector>
#include <map>
#include <queue>
#include <set>
#include <ctime>
#include <cstring>
#include <cstdlib>
#include <math.h>
using namespace std;
typedef long long ll;
//#define ll long long
const ll N = 2009;
const ll maxn = 1e5 + 20;
const ll mod = 1000000007;
//ll inv[maxn], vis[maxn], dis[maxn], head[maxn];
int fac[maxn], a[maxn], q[maxn], b[N], c[N], pre[maxn];
vector<ll> vec;
//typedef pair<ll, ll> p;
//priority_queue<p, vector<p>, greater<p> > m;
// ll sum[maxn], a[maxn];
ll max(ll a, ll b) { return a > b ? a : b; }
ll min(ll a, ll b) { return a < b ? a : b; }
ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
ll lcm(ll a, ll b) { return a * b / gcd(a, b); }
map<ll, ll> mp;
ll ksm(ll a, ll b)
{
    a %= mod;
    ll ans = 1ll;
    while (b)
    {
        if (b & 1)
            ans = (ans * a) % mod;
        a = (a * a) % mod;
        b >>= 1ll;
    }
    return ans;
}
int vis[N][N];
int dir[4][2] = {0, 1, 1, 0, 0, -1, -1, 0};
// void dfs(int x, int y)
// {
//     cout << x << ' ' << y << endl;
//     vis[x][y] = 1;
//     for (int i = 0; i < 4; i++)
//     {
//         int xx = x + dir[i][0], yy = y + dir[i][1];
//         if (xx <= 0)
//             xx = n;
//         if (yy <= 0)
//             yy = m;
//         if (xx > n)
//             xx = 1;
//         if (yy > m)
//             yy = 1;
//         if (!vis[xx][yy])
//             dfs(xx, yy);
//     }
// }
int n,m;
bool check(int x)
{
    bool fla;
    for (int i = 1; i <= n; i++)
    {
        fla = false;
        for (int j = 1; j <= m; j++)
        {
            if (((a[i] & b[j]) | x) == x)
            {
                fla = true;
                break;
            }
        }
        if (!fla)
            return false;
    }
    return true;
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    ll t;
    // cin >> t;
    // while (t--)
    // {
    //     memset(vis,0,sizeof vis);
    int ans;
    cin >> n >> m;
    for (int i = 1; i <= n; i++)
        cin >> a[i];
    for (int i = 1; i <= m; i++)
        cin >> b[i];

    for (int i = 0; i < (1 << 9); i++)
        if (check(i))
        {
            ans = i;
            break;
        }
    cout << ans << endl;
    // }
}

D − B o b o n i u D - Boboniu DBoboniu C h a t s Chats Chats w i t h with with D u Du Du

思路:
这个题是可以进行 O ( n ) O(n) O(n)枚举的,我们先求出不被禁言的玩笑值数组,再求会被的禁言的玩笑值数组,然后枚举被禁言的次数,我们把前 k − 1 k-1 k1次禁言放最前面,第k次禁言放后面,中间放不被禁言的,那么答案为:禁言 k − 1 k-1 k1次的玩笑值+不被禁言的玩笑值+第k次被禁言的玩笑值,对这些玩笑值进行排序,每次都取当前能取最大的。

参考代码:

#include <cstdio>
#include <algorithm>
#include <iostream>
#include <vector>
#include <map>
#include <queue>
#include <set>
#include <ctime>
#include <cstring>
#include <cstdlib>
#include <math.h>
using namespace std;
typedef long long ll;
//#define ll long long
const ll N = 2009;
const ll maxn = 1e5 + 20;
const ll mod = 1000000007;
//ll inv[maxn], vis[maxn], dis[maxn], head[maxn];
ll fac[maxn], a[maxn], q[maxn], b[maxn], c[maxn], pre[maxn];
vector<ll> vec;
//typedef pair<ll, ll> p;
//priority_queue<p, vector<p>, greater<p> > m;
ll sum[maxn];
ll max(ll a, ll b) { return a > b ? a : b; }
ll min(ll a, ll b) { return a < b ? a : b; }
ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
ll lcm(ll a, ll b) { return a * b / gcd(a, b); }
map<ll, ll> mp;
ll ksm(ll a, ll b)
{
    a %= mod;
    ll ans = 1ll;
    while (b)
    {
        if (b & 1)
            ans = (ans * a) % mod;
        a = (a * a) % mod;
        b >>= 1ll;
    }
    return ans;
}
int vis[N][N];
int dir[4][2] = {0, 1, 1, 0, 0, -1, -1, 0};
// void dfs(int x, int y)
// {
//     cout << x << ' ' << y << endl;
//     vis[x][y] = 1;
//     for (int i = 0; i < 4; i++)
//     {
//         int xx = x + dir[i][0], yy = y + dir[i][1];
//         if (xx <= 0)
//             xx = n;
//         if (yy <= 0)
//             yy = m;
//         if (xx > n)
//             xx = 1;
//         if (yy > m)
//             yy = 1;
//         if (!vis[xx][yy])
//             dfs(xx, yy);
//     }
// }
int n, m;
bool check(int x)
{
    bool fla;
    for (int i = 1; i <= n; i++)
    {
        fla = false;
        for (int j = 1; j <= m; j++)
        {
            if (((a[i] & b[j]) | x) == x)
            {
                fla = true;
                break;
            }
        }
        if (!fla)
            return false;
    }
    return true;
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    ll t;
    // cin >> t;
    // while (t--)
    // {
    //     memset(vis,0,sizeof vis);
    ll ans = 0, k1, k2, d;
    k1 = k2 = 0;
    cin >> n >> d >> m;
    for (int i = 1; i <= n; i++)
    {
        cin >> a[i];
        if (a[i] <= m)
            b[++k1] = a[i];
        else
            c[++k2] = a[i];
    }
    sort(b + 1, b + 1 + k1, greater<int>());
    sort(c + 1, c + 1 + k2, greater<int>());
    for (int i = 1; i <= n; i++)
        sum[i] = sum[i - 1] + b[i];
    ll res = 0;
    ans = sum[n];
    for (int i = 1; i <= k2; i++)
    {
        res += c[i];
        int p = (i - 1) * (d + 1) + 1;
        if (n - p < 0)
            break;
        p = n - p;
        ans = max(ans, res + sum[p]);
    }
    cout << ans << endl;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值