首页 > 其他分享 >AtCoder Beginner Contest 336

AtCoder Beginner Contest 336

时间:2024-02-01 21:25:44浏览次数:24  
标签:AtCoder le 数列 Beginner int ll 336 long dp

ABC336 总结

AtCoder Beginner Contest 336

A - Long Loong

翻译

给定一个数 \(n\),请输出一个由一个 L、\(n\) 个 o 、一个 n 和一个 g 组成的字符串(区分大小写)。

分析

按题意模拟即可。

code

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+5;

int n;

int main ()
{
    cin>>n;
    cout<<"L";
    for(int i=1;i<=n;i++) cout<<"o";
    cout<<"ng"<<"\n";
    return 0;
}

B - CTZ

翻译

求一个正整数 \(N\) 二进制下末尾 \(0\) 的个数,\(1\le N\le 10^9\)。

分析

直接 lowbit 操作,然后取 \(2\) 的对数。

code

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

int n,m;

int main ()
{
    cin>>n;
    m=n&(-n);
    cout<<log2(m)<<"\n";
    return 0;
}

C - Even Digits

翻译

定义满足没有前导零,且十进制下每个数位都为偶数的非负整数为好数。

求第 \(N\) 小的好数。\(1\le N\le 10^{12}\)。

分析

每个数位都是偶数,则每个数位都有五种情况,相当于把 \(n\) 转化为 \(5\) 进制数,再按照十进制来乘 \(2\)。

code

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+5;

ll n,m,t,a;

int main ()
{
    cin>>n;
    n--;
    while(n)
    {
        m=n%5;
        n/=5;
        a+=m*t;
        t*=10;
    }
    cout<<a*2<<"\n";
    return 0;
}

D - Pyramid

翻译

对于正整数 \(k\),一个大小为 \(k\) 的“金字塔数列”为一个长度为 \(2k-1\) 的数列,里面的数字依次为 \(1,2,3,\dots k-1,k,k-1,\dots 3,2,1\)。
现在给一个长度为 \(n\) 的数列 \(S\),你可以进行以下操作任意次,使得数列最后变为一个“金字塔数列”:

  • 选择一个数 \(i(1 \le i \le n)\),把 \(S_i\) 减少 \(1\)。
  • 删除整个数列的第一个或最后一个数字。

问最后生成的“金字塔数列”的最大的 \(k\) 是多少。

分析

\(k\) 大小的“金字塔数列”,前 \(k\) 项单调递增,后 \(k\) 项单调递减,可以分开考虑,用线性 \(dp\)。\(dp[i][0]\) 表示以 \(a_i\) 为末尾的,经过多次操作可以成为金字塔数列前 \(k\) 项的序列的最大长度,\(dp[i][1]\) 表示以 \(a_i\)为首的,经过多次操作可以成为金字塔数列后 \(k\) 项的最大长度,最终合并计算答案即可。

\[dp[i][0]=min(dp[i-1][0]+1,a[i]) \]

\[dp[i][1]=min(dp[i+1][1]+1,a[i]) \]

\[ans=max(ans,min(dp[i][0],dp[i][1])) \]

code

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+5;

int n,m,t,a[N],dp[N][3],ans;
int main ()
{
    cin>>n;
    for(int i=1;i<=n;i++) cin>>a[i];
    for(int i=1;i<=n;i++) dp[i][0]=min(dp[i-1][0]+1,a[i]);
    for(int i=n;i>=1;i--) dp[i][1]=min(dp[i+1][1]+1,a[i]);
    for(int i=1;i<=n;i++) ans=max(ans,min(dp[i][0],dp[i][1]));
    cout<<ans<<"\n";
    return 0;
}

F - Rotation Puzzle

翻译

gsczl71 有一个 \(H\) 行,\(W\) 列的二维数组。

每一次选择一个 \(H-1\) 行,\(W-1\) 列的连续矩阵,将其旋转 \(180\) 度。

目标:对于所有 \(1 \le i \le H,1 \le j \le W\),使得单元格 \((i,j)\) 中包含整数 \(\left(\left(i-1\right) \times W+j\right)\)。

你有最多 \(20\) 次操作机会,问你最少操作多少次?

若不可以达到要求,输出 -1

分析

翻转只有四种情况,最大操作次数为 \(20\),直接搜索状态数可达 \(4^{20}=1099511627776\),直接爆掉,但如果用双向搜索(meet in the middle),每个方向最大深度为 \(10\),这样状态数则为 \(2 \times 4^{10}=2097152\),轻松通过。

初状态与末状态等价,两者相遇可用特殊的值来判断,比如初状态为 \(1\),末状态为 \(2\),那么判断相遇就是值为 \(3\) 的时候。初末状态等价,可以只用一个队列,翻转操作需要略加思考,容易出错。可以用 stringmap 实现 hash,将二维数组转化为字符串和字符串还原为数组与八数码相同。

注意:原数组出现相同的数则一定无法实现,输出 -1,初末状态相同就不需要操作,输出 0

code

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=10;

int m,n,a[N][N],b[N][N],tong[N*N],f[5][3]={{1,1},{0,1},{1,0},{0,0}},c[N][N];
string st,ed;
map<string,int> vis,d,v;
string reverse(int x,int y)
{
    string s;
    for(int i=1;i<n;i++)
        for(int j=1;j<m;j++)
                c[i+x][j+y]=b[n-i+x][m-j+y];
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            s+=c[i][j]+'0';
    return s;    
}
void restore(string s)
{
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            c[i][j]=b[i][j]=s[(i-1)*m+j-1]-'0';
}
int bfs(string x,string y)
{
    queue<string> q;
    q.push(x);q.push(y);
    vis[x]=1;d[x]=0;
    vis[y]=2;d[y]=0;
    while(q.size())
    {
        string t=q.front();q.pop();
        for(int i=0;i<4;i++)
        {
            restore(t);
            int l=f[i][0],r=f[i][1];
            string s=reverse(l,r);
            if(vis[s]==vis[t]) continue;
            if(vis[s]+vis[t]==3) return d[s]+1+d[t];
            d[s]=d[t]+1;
            if(d[s]>10) return 21;
            vis[s]=vis[t];
            q.push(s);
        }
    }
    return 21;
}
int main ()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        {
            cin>>a[i][j];
            st+=a[i][j]+'0';
            tong[a[i][j]]++;
        }
    for(int i=1;i<=n*m;i++) 
    {
        if(tong[i]!=1) 
        {
            cout<<-1<<"\n";
            return 0;
        }
        ed+=i+'0';
    }
    if(ed==st)
    {
        cout<<0<<"\n";
        return 0;
    }
    int ans=bfs(st,ed);
    if(ans>20) cout<<-1<<"\n";
    else cout<<ans<<"\n";
    return 0;
}

标签:AtCoder,le,数列,Beginner,int,ll,336,long,dp
From: https://www.cnblogs.com/zhouruoheng/p/18002067

相关文章

  • AtCoder Beginner Contest 337 D
    AtCoderBeginnerContest337DD-CheatingGomokuNarabe题意:\(W\)列的矩阵,矩阵由o、x、.三种字符组成。你可以进行若干次操作(可以不做),每次操作可以把矩阵中的一个.改成o。请问最少经过多少次操作后,能在矩阵中找到位于同一行或同一列的连续\(K\)个o。思路:这题......
  • AtCoder Regular Contest 170
    A贪心。首先判无解。如果一个位置要变成A,那么它右边必须要有个B。如果一个位置要变成B,那么它右边必须要有个A。然后算答案,首先有一个明显的上限:\[\sum_{i=1}^{n}[s_i\neqt_i]\]假设我们有\(i\)位置要变成A,\(j\)位置要变成B,且\(i<j\),那么可以减少一次操作,扫一遍......
  • AtCoder Beginner Contest 338
    ABC338总结A-Capitalized?翻译给你一个由大写和小写英文字母组成的非空字符串\(S\)。请判断是否满足以下条件:\(S\)的第一个字符是大写字母,其他所有字符都是小写字母。如果满足,输出Yes,否则输出No。分析按题目说的判断即可。code#include<bits/stdc++.h>usingn......
  • AtCoder Beginner Contest 337
    ABC337总结A.Scoreboard翻译Takahashi队和Aoki队进行了\(N\)场比赛。在\(i\)/th比赛\((1\leqi\leqN)\)中,Takahashi队得了\(X_i\)分,Aoki队得了\(Y_i\)分。在\(N\)场比赛中总得分较高的队伍获胜。输出获胜者。如果两队总得分相同,则输出Draw。分析将得分分别加起来......
  • AtCoder Beginner Contest 338 c题二分思路
    观察题目可知,会有一个最大的x(两个菜的最大制作数),大于这个x就不能做任何一盘菜,小于这个x那么一定可以做出来,这样分析就是显而易见的递归。实现递归的check函数,那么我们就可以把两个菜的总制作数传进去。那么什么时候true什么时候false呢,就是判断每种材料的制作量有没有超过原材料......
  • AtCoder Beginner Contest 338
    A-Capitalized?#include<bits/stdc++.h>usingnamespacestd;#defineintlonglongusingvi=vector<int>;usingi32=int32_t;usingpii=pair<int,int>;constintinf=1e9,INF=1e18;i32main(){strings;cin>>......
  • AtCoder Beginner Contest 338
    基本情况A忘记大小写敏感卡了20分钟,BC秒了,E用树状数组草过去了,D错了25个点,似乎是交界没有判断好。B-FrequencyB-Frequency(atcoder.jp)这题还可以更优雅点。intmain(){strings;cin>>s;map<char,int>cnt;for(inti=0;i<s.size();i++......
  • AtCoder Beginner Contest 338
    基本情况:A和B直接秒了,C题没写出来大致是思路的问题,下面就讲一下C自己的思路和题解C-LeftoverRecipes题目概述,先输入一个数字代表有多少中配料,然后依次输入A菜每种配料所需的量,然后输入B菜每种配料所需的量,最后输出最多可以做多少盘菜样例:280030010010020010输出为......
  • AtCoder Beginner Contest 338
    AtCoderBeginnerContest338ABC切ABC,什么实力。C-LeftoverRecipesProblemStatementYourrefrigeratorhas\(N\)kindsofingredients.Letuscallthemingredient\(1\),\(\dots\),ingredient\(N\).Youhave\(Q_i\)gramsofingredient\(i\).......
  • AtCoder Beginner Contest 338
    AtCoderBeginnerContest338A-Capitalized?代码:#include<bits/stdc++.h>usingnamespacestd;usingll=longlong;usingpii=pair<ll,ll>;#definefifirst#definesesecondusingi128=__int128_t;voidsolve(){strings;cin&......