Codeforces Round #767 (Div. 2)

Codeforces Round #767 (Div. 2)

A. Download More RAM

题意:现有\(k\) GB的RAM,每次可以运行所需RAM不大于现有RAM的软件,运行完后额外获得相应的RAM,问最终可以拥有最大RAM。

思路:贪心,优先找RAM需求小的软件即可。

/* Author: cyanine_farewell
 * Time: 2022-01-22 22:35:03
**/
#include<bits/stdc++.h>
#define pb push_back
#define ll long long
#define fast ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
using namespace std;
const int maxn = 100010;
struct node{
    int a,b;
} s[maxn];
bool cmp(node a,node b)
{
    return a.a<b.a;
}
int main()
{
    fast;
    int T;
    cin>>T;
    while(T--)
    {
        int n,k;
        cin>>n>>k;
        for(int i=1;i<=n;i++)
        {
            cin>>s[i].a;
        }
        for(int i=1;i<=n;i++)
        {
            cin>>s[i].b;
        }
        sort(s+1,s+n+1,cmp);
        for(int i=1;i<=n;i++)
        {
            if(s[i].a<=k)
            {
                k+=s[i].b;
            }
        }
        cout<<k<<'\n';
    }
    return 0;
}

B. GCD Arrays

题意:给出\([l,r]\)的序列,可执行如下操作:选择序列中的两个数,删去这两个数并将他们的乘积加入序列。问能否在\(k\)次操作内,使得序列中所有数字的最大公因数不为\(1\)

思路:贪心。尽量将所有数变为偶数,只需要判断序列中奇数个数是否不大于\(k\)即可。另外需要特判\(k=0\)的情况。

/* Author: cyanine_farewell
 * Time: 2022-01-22 22:35:03
**/
#include<bits/stdc++.h>
#define pb push_back
#define ll long long
#define fast ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
using namespace std;
const int maxn = 100010;
int main()
{
    fast;
    int T;
    cin>>T;
    while(T--)
    {
        int l,r,k;
        cin>>l>>r>>k;
        if(k==0 && r==l)
        {
            if(l==1) cout<<"NO\n";
            else cout<<"YES\n";
            continue;
        }
        int num=(r-l)/2;
        if(l%2==0 || r%2==0) num++;
        if(k>=(r-l+1-num)) cout<<"YES\n";
        else cout<<"NO\n";
    }
    return 0;
}

C. Meximum Array

题意:给出\(n\)个数,每次可以任意选取前\(k\)个数,求出其\(mex\)并加入结果序列中,重复操作,求字典序最大的结果。

思路:贪心。每次找到\(mex\)结果最大的最早出现位置。方法为:从左到右记录每个数字出现的位置,若当前初始位置为\(pos\),从小到大更新\(mex\)结果最大的最早出现位置\(temppos\),若后续不存在该数,\(mex\)结果即为该数,\(pos=temppos+1\)。每一轮结束后需要维护将每个数在\(pos\)前的位置记录删去。

/* Author: cyanine_farewell
 * Time: 2022-01-22 22:35:03
**/
#include<bits/stdc++.h>
#define pb push_back
#define ll long long
#define fast ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
using namespace std;
const int maxn = 200010;
int n;
int a[maxn];
queue<int> v[maxn];
vector<int> ans;
int main()
{
    fast;
    int T;
    cin>>T;
    while(T--)
    {
        ans.clear();
        cin>>n;
        for(int i=0;i<=n;i++)
        {
            while(!v[i].empty()) v[i].pop();
        }
        for(int i=1;i<=n;i++)
        {
            cin>>a[i];
            v[a[i]].push(i);
        }
        int pos=1;
        while(pos<=n)
        {
            int temppos=pos;
            // cout<<pos<<'\n';
            for(int i=0;i<=n+1;i++)
            {
                while(!v[i].empty() && v[i].front()<pos) v[i].pop();
                if(v[i].empty())
                {
                    pos=temppos+1;
                    ans.pb(i);
                    break;
                }
                temppos=max(temppos,v[i].front());
            }
        }
        cout<<ans.size()<<'\n';
        for(int i=0;i<ans.size();i++)
        {
            cout<<ans[i]<<' ';
        }
        cout<<'\n';
    }
    return 0;
}

D. Peculiar Movie Preferences

题意:给出\(n\)个长度不大于\(3\)的字符串,问其子序列拼接而成的字符串是否回文串。

思路:分如下几种情况:

(1) 出现长度为\(1\)的字符串,结果为YES。

(2) 出现长度为\(3\)的字符串,需要判断字符串首尾是否相同,若存在,结果为YES。

(3) 剩下为组合的字符串,只需要考虑长度\(2+2,2+3,3+2,3+3\)四种情况即可,分类写即可。

/* Author: cyanine_farewell
 * Time: 2022-01-22 22:35:03
**/
#include<bits/stdc++.h>
#define pb push_back
#define ll long long
#define fast ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
using namespace std;
const int maxn = 100010;
int n;
string s[maxn];
vector<string> v[4];
map<string,bool> pre;
int len[10];
int main()
{
    fast;
    int T;
    cin>>T;
    while(T--)
    {
        pre.clear();
        for(int i=1;i<=3;i++)
        {
            v[i].clear();
        }
        cin>>n;
        for(int i=1;i<=n;i++)
        {
            cin>>s[i];
            v[s[i].length()].pb(s[i]);
        }
        if(v[1].size()!=0)
        {
            cout<<"YES\n";
            continue;
        }
        bool flag=0;
        if(v[2].size()!=0)
        {
            for(int i=0;i<v[2].size();i++)
            {
                if(v[2][i][0]==v[2][i][1])
                {
                    flag=1;
                    break;
                }
            }
            if(flag)
            {
                cout<<"YES\n";
                continue;
            }
        }
        if(v[3].size()!=0)
        {
            for(int i=0;i<v[3].size();i++)
            {
                if(v[3][i][0]==v[3][i][2])
                {
                    flag=1;
                    break;
                }
            }
            if(flag)
            {
                cout<<"YES\n";
                continue;
            }
        }
        for(int i=1;i<=n;i++)
        {
            if(s[i].length()==3)
            {
                string s1="",s2="";
                s1+=s[i][0];
                s1+=s[i][1];
                s2+=s[i][2];
                s2+=s[i][1];
                s1+=s[i][2];
                s2+=s[i][0];
                if(pre[s2])
                {
                    flag=1;
                    break;
                }
                pre[s1]=1;
            }
        }
        if(flag)
        {
            cout<<"YES\n";
            continue;
        }
        pre.clear();
        for(int i=1;i<=n;i++)
        {
            if(s[i].length()==3)
            {
                string s1="",s2="";
                s1+=s[i][0];
                s1+=s[i][1];
                pre[s1]=1;
            }
            if(s[i].length()==2)
            {
                string s1="";
                s1+=s[i][1];
                s1+=s[i][0];
                // cout<<s[i]<<' '<<s1<<'\n';
                if(pre[s1])
                {
                    flag=1;
                    break;
                }
                pre[s[i]]=1;
            }
        }
        if(flag)
        {
            cout<<"YES\n";
            continue;
        }
        pre.clear();
        for(int i=1;i<=n;i++)
        {
            if(s[i].length()==3)
            {
                string s1="",s2="";
                s2+=s[i][2];
                s2+=s[i][1];
                if(pre[s2])
                {
                    flag=1;
                    break;
                }
            }
            if(s[i].length()==2)
            {
                string s1="";
                s1+=s[i][1];
                s1+=s[i][0];
                // cout<<s[i]<<' '<<s1<<'\n';
                if(pre[s1])
                {
                    flag=1;
                    break;
                }
                pre[s[i]]=1;
            }
        }
        if(flag)
        {
            cout<<"YES\n";
            continue;
        }
        cout<<"NO\n";
    }
    return 0;
}

E. Grid Xor

题意:给出\(n\cdot n\)的矩阵,每个数代表原矩阵周围四个数的异或和,求出原矩阵的异或和。

思路:任意确定第一行的值,后续的值按照\(b[i][j]=a[i-1][j]\bigoplus b[i-1][j-1]\bigoplus b[i-1][j+1]\bigoplus b[i-2][j]\)确认即可。无论矩阵如何最终的异或和是一样的。

/* Author: cyanine_farewell
 * Time: 2022-01-22 22:35:03
**/
#include<bits/stdc++.h>
#define pb push_back
#define ll long long
#define fast ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
using namespace std;
const int maxn = 1010;
int a[maxn][maxn];
int b[maxn][maxn];
int main()
{
    fast;
    int T;
    cin>>T;
    while(T--)
    {
        int n;
        cin>>n;
        for(int i=0;i<=n+1;i++)
        {
            for(int j=0;j<=n+1;j++)
            {
                b[i][j]=0;
            }
        }
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
            {
                cin>>a[i][j];
            }
        }
        for(int i=1;i<=n;i++)
        {
            b[1][i]=675014;
        }
        for(int i=2;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
            {
                b[i][j]=a[i-1][j]^b[i-1][j-1]^b[i-1][j+1]^b[i-2][j];
            }
        }
        int ans=0;
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
            {
                ans^=b[i][j];
            }
        }
        cout<<ans<<'\n';
    }
    return 0;
}

F. Game on Sum

题意:给定游戏轮数\(n\),必须得分轮数\(m\)与可选取最大值\(k\),每次Alice可以选择\(1-k\)的任意分数,Bob可以选择这次是加分还是减分,加分次数必须为\(m\)。问最终分数的期望。

思路1:设\(dp[i][j]\)为已选取\(i\)个数,加分次数为\(j\)分数的期望值。初始条件为:次数\(j=0\)\(dp[i][j]=0\)\(i=j\)\(dp[i][j]=i*k\)若Bob选择加分,则\(dp[i][j]=dp[i-1][j-1]+x\),若选择减分,则\(dp[i][j]=dp[i-1][j]-x\),那么最终期望为\(dp[i][j]=(dp[i-1][j-1]+dp[i-1][j])/2\)

思路2:对于\(dp[n][m]\)其实有很多不必要的转移参与讨论。而\(dp[i][i]\)的值是可以很容易得到的,所以可以只讨论\(dp[i][i]\)\(dp[n][m]\)的转移。对于每一个\(i\)\(dp[i][i]\)\(dp[n][m]\)可以理解为在\(n-i\)次操作中加法次数为\(m-i\)的转移,考虑\(dp[i][i]\)不能影响后续的\(dp[i+1][i+1]\),因此操作数\(-1\),这个条件下的情况一共有\(C^{m-i}_{n-i-1}\)。计算贡献时由于每次转移需要\(/2\),因此最终的贡献需要\(/2^{n-i}\)

/* Author: cyanine_farewell
 * Time: 2022-01-22 22:35:03
**/
#include<bits/stdc++.h>
#define pb push_back
#define ll long long
#define fast ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
using namespace std;
const int maxn = 2010;
const int mod = 1e9+7;
ll f[maxn][maxn];
ll n,m,k;
ll Pow(ll a,ll b)
{
    if(b==0) return 1;
    if(b%2) return a*Pow(a,b-1)%mod;
    ll tmp=Pow(a,b/2);
    return tmp*tmp%mod;
}
int main()
{
    fast;
    int T;
    cin>>T;
    while(T--)
    {
        ll inv2=Pow(2,mod-2)%mod;
        cin>>n>>m>>k;
        for(int i=1;i<=n;i++)
        {
            f[i][0]=0;
            f[i][i]=k*i%mod;
        }
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
            {
                if(i==j) continue;
                f[i][j]=(f[i-1][j-1]+f[i-1][j])%mod*inv2%mod;
            }
        }
        cout<<f[n][m]<<'\n';
    }
    return 0;
}
/* Author: cyanine_farewell
 * Time: 2022-01-22 22:35:03
**/
#include<bits/stdc++.h>
#define pb push_back
#define ll long long
#define fast ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
using namespace std;
const int maxn = 1000010;
const int mod = 1e9+7;
ll f[maxn];
ll n,m,k;
ll fac[maxn];
ll Pow(ll a,ll b)
{
    if(b==0) return 1;
    if(b%2) return a*Pow(a,b-1)%mod;
    ll tmp=Pow(a,b/2);
    return tmp*tmp%mod;
}
void init()
{
    fac[0]=1;
    for(int i=1;i<=1e6;i++)
    {
        fac[i]=fac[i-1]*i%mod;
    }
}
ll C(ll n,ll m)
{
    return fac[n]*Pow(fac[n-m]*fac[m]%mod,mod-2)%mod;
}
int main()
{
    fast;
    init();
    int T;
    cin>>T;
    ll inv2=Pow(2,mod-2);
    while(T--)
    {
        ll ans=0;
        cin>>n>>m>>k;
        if(n==m)
        {
            cout<<n*k%mod<<'\n';
            continue;
        }
        for(int i=1;i<=m;i++)
        {
            ans=ans+C(n-i-1,m-i)*Pow(inv2,n-i)%mod*i%mod;
            ans=ans%mod;
        }
        cout<<ans*k%mod<<'\n';
    }
    return 0;
}
posted @ 2022-01-23 16:46  cyanine_告别  阅读(109)  评论(0编辑  收藏  举报