自学内容网 自学内容网

Educational Codeforces Round 170 (Rated for Div. 2) A-D

本期封面原图 画师るかちか 舞台剧篇的阿夸确实帅 当时看漫画就惊艳到我了
虽然下午练了两场但还是太久没打 哐哐掉分了😭😭😭

Educational Codeforces Round 170 (Rated for Div. 2)

A. Two Screens

题意

两个屏幕都要显示字符串,每次操作可以多打一个字符或者用一个屏幕覆盖另一块上的内容,最小化操作次数

思路

跟下午ABC374的B题很像啊,加一个计算就行

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;

void solve()
{
    string s, t;
    cin >> s >> t;
    int n = min(s.length(), t.length());
    for (int i = 0; i < n; i++)
    {
        if (s[i] != t[i])
        {
            if(i==0)
            {
                printf("%d\n",s.length()+t.length());
                return ;
            }
            printf("%d\n", s.length()-(i+1)+1+t.length()-(i+1)+1+i+1);
            return ;
        }
    }
    if (s.length() == t.length())
        printf("%d\n",n+1);
    else
        printf("%d\n", s.length()-(n+1)+1+t.length()-(n+1)+1+n+1);
}

int main()
{
    int T=1;
    scanf("%d",&T);
    while(T--)
    {
        solve();
    }
    return 0;
}

B. Binomial Coefficients, Kind Of

题意

有人把求组合数的预处理函数打成了这样

for (int n = 0; n < N; n++) { // loop over n from 0 to N-1 (inclusive)
        C[n][0] = 1;
        C[n][n] = 1;
        for (int k = 1; k < n; k++) // loop over k from 1 to n-1 (inclusive)
            C[n][k] = C[n][k - 1] + C[n - 1][k - 1];
    }

要你以更快的速度求这个错误的答案

思路

打表发现直接输出 2 k 2^k 2k即可,除了最后一个特判

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
const ll mod=1e9+7;

ll qpow(ll a,ll b)
{
    ll res=1;
    while(b)
    {
        if(b&1)
        {
            res=res*a%mod;
        }
        a=a*a%mod;
        b>>=1;
    }
    return res;
}

void solve()
{
    ll t;
    scanf("%lld",&t);
    ll n[t+1],k[t+1];
    for(ll i=1;i<=t;i++)
    {
        scanf("%lld",&n[i]);
    }
    for(ll i=1;i<=t;i++)
    {
        scanf("%lld",&k[i]);
    }
    for(int i=1;i<=t;i++)
    {
        ll N=n[i],K=k[i];
        if(K==0 or K==N)
            printf("1\n");
        else
            printf("%lld\n",qpow(2ll,K));
    }
}

int main()
{
    int T=1;
//    scanf("%d",&T);
    while(T--)
    {
        solve();
    }
    return 0;
}

C. New Game

题意

拿牌,除了第一张每次可以拿前一张牌相同的或数字比前一张大1的牌,最多有k种不同数字,最大化牌数

思路

贪心地想肯定每种牌要拿完,就需要开桶记录每个数字的出现次数,然后滑动窗口就行了

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
const int N=2e5+5;
map<ll,ll> a;
ll b[N];
int n,k;

void solve()
{
    scanf("%d%d",&n,&k);
    a.clear();
    for(int i=1;i<=n;i++)
    {
        ll x;
        scanf("%lld",&x);
        a[x]++;
        b[i]=x;
    }
    sort(b+1,b+n+1);
    ll len=unique(b+1,b+n+1)-b-1;
    ll l=b[1],r=b[1];
    ll sum=a[b[1]];
    ll ans=sum;
    for(int i=2;i<=len;i++)
    {
        if(b[i]-r==1)
        {
            if (b[i] - l < k)
            {
                r++;
                sum += a[b[i]];
                ans = max(ans, sum);
            }
            else
            {
                sum -= a[l];
                l++;
                r++;
                sum += a[b[i]];
                ans = max(ans, sum);
            }
        }
        else
        {
            l=b[i];
            r=b[i];
            sum=a[b[i]];
            ans=max(ans,sum);
        }
    }
    printf("%lld\n",ans);
}

int main()
{
    int T=1;
    scanf("%d",&T);
    while(T--)
    {
        solve();
    }
    return 0;
}

D. Attribute Checks

题意

打关卡,有的关卡给你一个可以自由分配的点数,有的关卡要求你的智力或力量达标可以获得一分,最大化你的最终得分

思路

我最讨厌的dp 下面有注释 不想说了

代码

#include <bits/stdc++.h>
#define mod 998244353
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
int smart[5001],strength[5001];
int pointSum=0;
int dp[5001][5001];
//i和j分别代表当前智商和当前体力

int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    memset(dp,0,sizeof(dp));
    memset(smart,0,sizeof(smart));
    memset(strength,0,sizeof(strength));
    ll ans=0;
    for(int i=1;i<=n+1;i++)
    {
//        printf("%d\n",i);
        int x;
        if(i<=n)
            scanf("%d",&x);
        else
            x=0;
        if(x>0)
        {
            smart[x]++;
            continue;
        }
        else if(x<0)
        {
            strength[-x]++;
            continue;
        }
        else
        {
            int delta=0;
            //前缀和,维护加上多少个点可以多过多少道关卡
            for(int j=0;j<=pointSum;j++)
            {
                delta+=smart[j];
                dp[j][pointSum-j]+=delta;
            }

            delta=0;
            for(int j=0;j<=pointSum;j++)
            {
                delta+=strength[j];
                dp[pointSum-j][j]+=delta;
            }

            //更新dp
            for(int j=0;j<=pointSum;j++)
            {
                dp[j+1][pointSum-j]=max(dp[j+1][pointSum-j],dp[j][pointSum-j]);
                //假如这个点点给了智商
                dp[j][pointSum-j+1]=max(dp[j][pointSum-j+1],dp[j][pointSum-j]);
                //假如这个点点给了体力
                ans=max(ans,(ll)(dp[j+1][pointSum-j]));
            }

            for(int j=0;j<=pointSum;j++)
            {
                dp[pointSum-j][j+1]=max(dp[pointSum-j][j+1],dp[pointSum-j][j]);
                //假如这个点点给了体力
                dp[pointSum-j+1][j]=max(dp[pointSum-j+1][j],dp[pointSum-j][j]);
                //假如这个点点给了智商
                ans=max(ans,(ll)(dp[pointSum-j][j+1]));
            }

            pointSum++;

            //清空
            for(int j=0;j<=5000;j++) smart[j]=strength[j]=0;
        }
    }
    printf("%lld\n",ans);
    return 0;
}

原文地址:https://blog.csdn.net/swan416/article/details/142932384

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!