首页 > 其他分享 >Codeforces Round 863 (Div. 3)

Codeforces Round 863 (Div. 3)

时间:2023-04-10 13:12:54浏览次数:42  
标签:int 863 Codeforces cin -- num maxn Div dp

题解报告

基本的一些理解和问题都在注释中
A:Insert Digit
找到第一个小于输入数字的数的位置塞进去就好了,可以细推,但是粗略想想也能知道

#include <bits/stdc++.h>
using namespace std;
int main(void)
{
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    int T;cin>>T;
    while(T--)
    {
        string s;
        int len,num;
        cin>>len>>num>>s;
        int flag=1;
        for(int i=0;i<len;i++)//遇到第一个小的就输出,等于的不行。一定等于的话不一定是最优秀的,
        {
            if(flag&&s[i]-'0'<num)cout<<num,flag=0;
            cout<<s[i];
        }
        if(flag)cout<<num;
        cout<<endl;
    }
    return 0;
}

B:Conveyor Belts
考虑离中间点的距离大的,然后判断各个点位在第几层,判断层数的距离就行了
注意离中间点的距离的计算就行了

#include <bits/stdc++.h>
using namespace std;
int main(void)
{
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    int T;cin>>T;
    while(T--)
    {
        int N,X1,Y1,X2,Y2;
        cin>>N>>X1>>Y1>>X2>>Y2;
        N=N/2;
        int DX1=N-X1;if(DX1<0)DX1=-DX1-1;
        int DY1=N-Y1;if(DY1<0)DY1=-DY1-1;
        int DX2=N-X2;if(DX2<0)DX2=-DX2-1;
        int DY2=N-Y2;if(DY2<0)DY2=-DY2-1;
        cout<<(int)abs(max(DX1,DY1)-max(DX2,DY2))<<endl;
    }
    return 0;
}

C:Restore the Array
这道题目既可以通过找规律,也可以通过模拟来进行构造
不过我没有写出来,菜是原罪,哎~~
画图!!!画图!!!画图!!!画图看关系是真的很重要

#include <bits/stdc++.h>
using namespace std;
const int maxn=2e5+10;
int num[maxn];
// int main(void)//方法一:不怎么好想
// {
//     ios::sync_with_stdio(false);
//     cin.tie(0);cout.tie(0);
//     int T;cin>>T;
//     while(T--)//取两个的间隔的max组成的数组是不可能存在(小-大-小)这种结构的,所以
//     {//在两个数中每次取小的,就可以在原数组的推导中每次都可以通过取大的取出那个数,因为一个数不是比右边的大,就是比左边的大,或者相等。
//         //一个数不可能同时比两边的大,所以这种方法一定可以按照顺序把每个数都取一遍。
//         //对于边界的值,如果直接放上B数组的边界,这样就可以保证所有的数都可以取到,
//         //边界的值可以放B数组边界的值,这样就可以保证不管是先取还是后取,都会有第一个数和最后一个数。
//         int N;cin>>N;
//         for(int i=0;i<N-1;i++)cin>>num[i];
//         cout<<num[0]<<' ';
//         for(int i=0;i<N-2;i++)cout<<min(num[i],num[i+1])<<' ';
//         cout<<num[N-2]<<endl;
//     }
//     return 0;
// }
int main(void)
{
    ios::sync_with_stdio(false);//比较容易想到
    cin.tie(0);cout.tie(0);
    int T;cin>>T;
    while(T--)
    {
        //不断的塞入数组进行模拟
        int N;cin>>N;
        for(int i=0;i<N-1;i++)cin>>num[i];
        vector<int> ans;
        ans.push_back(num[0]);
        int cnt=1;
        for(int i=1;i<N-1;i++)
        {
            if(cnt==i){//决定别人的时候
                if(ans.back()<num[i])cnt++,ans.push_back(0);
                ans.push_back(num[i]);
                cnt++;
            }else{//决定自己的时候
                if(ans.back()<num[i])cnt++,ans.push_back(num[i]);
            }
        }
        if(ans.size()!=N)ans.push_back(0);
        for(int i=0;i<N;i++)cout<<ans[i]<<' ';
        cout<<endl;
    }
    return 0;
}

D:Umka and a Long Flight
想像每增加一个正方形后,长度为1的正方形可以怎么变换就行了
长度为1的正方形可以怎么位移?水平方向上的移动是怎么样的,可以怎么移动?竖直方向是怎么样的?

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=50;
ll Fib[maxn];
void init()
{
    Fib[0]=1;Fib[1]=1;
    for(int i=2;i<maxn;i++)
        Fib[i]=Fib[i-1]+Fib[i-2];
}
int main(void)
{
    int T;cin>>T;
    init();
    while(T--)
    {
        ll N,X,Y;
        cin>>N>>X>>Y;
        int flag=N&1;
        for(int i=N;i>=1;i--)if((i&1)!=flag&&X-Fib[i]>=1)X-=Fib[i];
        for(int i=N;i>=1;i--)if((i&1)==flag&&Y-Fib[i]>=1)Y-=Fib[i];
        if(X==1&&Y==1)cout<<"YES"<<endl;
        else cout<<"NO"<<endl;
    }
    return 0;
}

E:Living Sequence
去掉一个数后就是九进制数,考虑每个数的组成后拆分就行了

#include <bits/stdc++.h>
#define ll long long
using namespace std;
int main(void)
{
    int T;cin>>T;
    while(T--)//就是个十进制化为九进制而已
    {
        ll N;cin>>N;
        ll ans=0,cnt=0;
        while(N)
        {
            ans+=pow(10,cnt)*((N%9)>=4?((N%9)+1):(N%9));
            N/=9;
            cnt++;
        }
        cout<<ans<<endl;
    }
    return 0;
}

G1:Vlad and the Nice Paths (easy version)
线性dp时,考虑自己这个位置是怎么被处理的,从操作的角度来考虑,既可以被除去,也能成为一部分
多多画图,看看状态之间是怎么转移的,各种操作会导致怎么样的状态

#include <bits/stdc++.h>
using namespace std;
const int maxn=1e2+10;
const int MOD=1e9+7;
int dp[maxn][maxn];//当前位置,有j个长度为K的序列的个数。
int C[maxn][maxn];
int num[maxn];
void init()//获取组合数的经典递推
{
    for(int i=0;i<maxn;i++)
    {
        C[0][i]=1;
        for(int j=1;j<=i;j++)
            C[j][i]=(C[j-1][i-1]+C[j][i-1])%MOD;
    }
}
int main(void)
{
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    init();
    int T;cin>>T;
    while(T--)
    {
        memset(dp,0,sizeof(dp));
        int N,K;cin>>N>>K;
        for(int i=1;i<=N;i++)cin>>num[i];
        if(K==1)//注意这里后面利用到了组合数,所以这里要先特判一下
        {
            cout<<1<<endl;
            continue;
        }
        dp[0][0]=1;
        for(int i=1;i<=N;i++)
        {
            dp[i][0]=1;
            for(int j=1;j<=N/K+1;j++)//对所有的情况进行更新。
            {
                int now=1;
                 for(int k=i-1;k>=1;k--)//枚举如果num[i]作为新的K位的时候的所有的可能性。
                {
                    if(num[k]==num[i])//利用组合算进行统计。
                    {
                        now++;
                        if(now>=K)dp[i][j]=(dp[i][j]+(1LL*dp[k-1][j-1]*C[K-2][now-2])%MOD)%MOD;
                    }
                }
                dp[i][j]=(dp[i][j]+dp[i-1][j])%MOD;//如果num[i]这位不算,那么它的可能就是前面的可能,这里要加上
            }
        }
        for(int i=N/K+1;i>=0;i--)//从长度最大的开始枚举。
        {
            if(dp[N][i])
            {
                cout<<dp[N][i]<<endl;
                break;
            }
        }
    }
    return 0;
}

G2:Vlad and the Nice Paths (hard version)
由于不需要每个长度的,所以只要记录最长的就行了,每次对最长的进行更新

#include <bits/stdc++.h>
using namespace std;
const int maxn=5e3+10;
const int MOD=1e9+7;
int dp[maxn],Max[maxn],num[maxn];//dp记录这个位置i前(包括这个位置i)长度为Max[i]的情况的个数,
//Max[i]记录这里可以有的满足题目条件的最长的分区数。
//num记录原数组
int C[maxn][maxn];
void init()
{
    for(int i=0;i<maxn;i++)
    {
        C[0][i]=1;
        for(int j=1;j<=i;j++)
            C[j][i]=(C[j-1][i-1]+C[j][i-1])%MOD;
    }
}
int main(void)
{
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    init();
    int T;cin>>T;
    while(T--)
    {
        memset(dp,0,sizeof(dp));
        memset(Max,0,sizeof(Max));
        int N,K;cin>>N>>K;
        for(int i=1;i<=N;i++)cin>>num[i];
        dp[0]=1;
        for(int i=1;i<=N;i++)
        {
            int now=1;
            for(int j=i-1;j>=1;j--)//num[i]作为dp[i]的最后一个的情况。
            {
                if(num[i]==num[j])
                {
                    now++;
                    if(now==K)Max[i]=Max[j-1]+1;//可以扩充的最长的
                    if(now>=K)
                    {
                        if(Max[i]!=Max[j-1]+1)break;//不是最长的了
                        dp[i]=(dp[i]+(1LL*dp[j-1]*C[K-2][now-2])%MOD)%MOD;
                    }
                }
            }
            //证明i之前最长的不是i开始的,所以i这里的组合不是要的,置为0
            if(Max[i]<Max[i-1])
            {
                dp[i]=0;
                Max[i]=Max[i-1];
            }
            //i可以继承i-1的集合,所以直接加上dp[i-1]的情况。
            //不作为最后一个考虑的情况。
            if(Max[i]==Max[i-1])dp[i]=(dp[i]+dp[i-1])%MOD;
        }
        cout<<dp[N]<<endl;
    }
    return 0;
}

F不太会,就不写了
掉分了,失败的一场比赛,哎~~

标签:int,863,Codeforces,cin,--,num,maxn,Div,dp
From: https://www.cnblogs.com/WUTONGHUA02/p/17302586.html

相关文章

  • Codeforces Round 865 (Div. 2)
    CodeforcesRound865(Div.2)A.IanVisitsMaryvoidsolve(){intx=read(),y=read();if(__gcd(y,x)!=1){cout<<2<<endl;cout<<1<<""<<y-1<<endl;cout<<x<<"&q......
  • 练习记录-cf-div2-865(A-C)
    反转就是写的非常烂Awa10其他还行吧丢人A.IanVisitsMary如果这两个数的gcd是1可以直接过去如果是0那就绕一个1过去变成三角形不然就用(1,b-1)到(a,1)这样就是两次的1不会遇到#include<bits/stdc++.h>#defineclosestd::ios::sync_with_stdio(false),cin.ti......
  • Codeforces Round 864 (Div. 2) C和D
    比赛地址C.LiHuaandChess题意:给出一个棋盘长宽n,m,有一颗棋子在棋盘上,向八个方向走一步的路程代价都为1,现在进行最多3次询问,问能否确认棋子的位置Solution第一次做交互题,想很好想,先询问(1,1),得到x,再询问(1+x,1+x),得到y,最后询问(1+x,1+x-y),如果得到的是0,则输出这个点,反之输......
  • 练习记录-cf-div2-856(A-C)
    vp的写出4道C感觉目前不是能力范围以后有机会留下来打比赛的话再说A-PrefixandSuffixArray给出字符串的前缀和后缀问是不是回文 我采用枚举长度为n-1和1的拼凑但是这并不奏效一直wa3后来改用拼两个n/2的就过了如果有大佬看到了希望能解答一下qwq#include<b......
  • 练习记录-cf-div2-864(A-D)
    状态不怎么好场上就写出3道还磨磨蹭蹭推错结论qwq 警钟长鸣A.LiHuaandMaze一开始以为要切割发现就把其中一个包起来就行了计算包某个块需要的最小块数#include<bits/stdc++.h>#defineclosestd::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)usingn......
  • Codeforces Round 860 (Div. 2)
    CodeforcesRound860(Div.2)Date:04/08/2023Link:CodeforcesRound860(Div.2)A|ShowstopperBrief:两组数\(\{a_i\}\)和\(\{b_i\}\),长度都为\(n\).\(\foralli\),可以交换\(a_i\)和\(b_i\),问是否可以使得\(a_n=\max(a_i)\),\(b_n=\max(b_i......
  • Codeforces Round 864 (Div. 2)
    评价:A~E感觉出的挺一般,特别是D怎么放这种暴力题,场上我还没调出来,F没看。但是Orzrui_er。A在一个点周围放障碍即可。B求出最少需要的操作次数\(p\),若\(p>k\)就无解,否则若\(n\)为偶数只能任选一个格子翻偶数次,即有解当且仅当\(2\mid(k-p)\);若\(n\)为奇数可......
  • Edu Round 板刷计划 4. Educational Codeforces Round 4 题解
    ChangeLog:2023.04.06开坑.A-TheTextSplitting弱智题.枚举分出来多少个长度为\(p\)的串,则能计算出长度为\(q\)的串有多少个,若合法则直接输出即可.无解输出-1.Samplesubmission.B-HDDisOutdatedTechnology比A还弱智.直接记录每个数的位置,然后模拟一......
  • codeforces 1804D Accommodation
    https://codeforces.com/problemset/problem/1804/D解题思路每个楼层是独立的,考虑怎么解决一层就可以了。求最大值就是尽量避免1和1合并,也就是尽量在不存在连续1的子序列中进行合并,如果还有需要合并的就只能用1和1合并。求最小值就是尽量合并1和1。由于只需要输出最大最小值,所......
  • Educational Codeforces Round 146 (Rated for Div. 2)
    A.Coins#include<bits/stdc++.h>usingnamespacestd;#defineintlonglongintread(){intx=0,f=1,ch=getchar();while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();if(ch......