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

AtCoder Beginner Contest 363

时间:2024-07-21 20:50:50浏览次数:6  
标签:AtCoder ch Beginner int long using include 363 回文

AtCoder Beginner Contest 363

A - Piling Up

每100分显示一个^。现在已知分数,问想要多显示一个^需要再得多少分。

模拟题,显示\(i\)个^的最小分数是\(100\times i\),而当前的^是\([\frac{R}{100}]\),\(R\)是当前的分数。

所以答案就是\(([\frac{R}{100}]+1)\times 100-R\)

#include<iostream>
#include<cstdio>
using namespace std;
int R;
int main()
{
    cin>>R;
    int display=R/100;
    cout<<(display+1)*100-R<<endl;
    return 0;
}

B - Japanese Cursed Doll

有\(n\)个数,第\(i\)个是\(L_i\),每个数在每个时刻都会增长\(1\)。问在哪个时刻第一次有\(P\)个数会大于等于\(T\)。如果初始时就满足条件,则输出\(0\)。

将\(L\)从小往大排序,那么只需要第\(n-P+1\)大的数满足条件即可,假设这个数是\(a\)。因此,只需要计算\(T-a\)即可。注意,如果这个数是负数,意味着初始时就满足条件,此时要输出\(0\)。

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int MAX=105;
int n,T,P;
int L[MAX];
int main()
{
    cin>>n>>T>>P;
    for(int i=1;i<=n;++i)cin>>L[i];
    sort(&L[1],&L[n+1]);
    int l=L[n-P+1];
    int ans=max(0,T-l);
    cout<<ans<<endl;
    return 0;
}

C - Avoid K Palindrome 2

有一个长度为\(n\)的字符串\(S\)。问有多少个字符串满足:1、通过\(S\)重排列得到;2、没有一个长度为\(K\)的回文子串。

注意数据范围,完全可以依次枚举每一个排列,可以使用next_permutation函数。接着暴力判断是否拥有回文子串即可。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n,k,ans;
char c[15];
int main()
{
    scanf("%d%d",&n,&k);
    scanf("%s",c+1);
    sort(&c[1],&c[n+1]);
    do    
    {
        bool flag=true;
        for(int i=1;i+k-1<=n;++i)
        {
            bool f=true;
            for(int j=0;j<k;++j)
                if(c[i+j]!=c[i+k-1-j])
                    f=false;
            if(f)flag=false;
        }
        if(flag)++ans;
    }while(next_permutation(&c[1],&c[n+1]));
    printf("%d\n",ans);
    return 0;
}

D - Palindromic Number

求第\(k\)大的回文数。

回文数只需要考虑前一半就可以构造。
枚举长度,首先计算出答案回文数的长度。通过枚举和减法可以计算出是当前长度下第\(k\)大的回文数。
而前一半就是顺序的,第\(k\)大就是当前长度的数的第\(k\)大,这个很好求。
接下来只需要构成回文,直接输出即可。

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
long long N;
long long fpow(long long a,long long b)
{
    long long ret=1;
    while(b)
    {
        if(b&1)ret*=a;
        a*=a;
        b>>=1;
    }
    return ret;
}
int a[1000];
int main()
{
    cin>>N;
    N-=1;
    if(N<10)
    {
        printf("%lld\n",N);
        return 0;
    }
    int l=1;
    while(true)
    {
        int t=(l+1)>>1;
        long long m=9ll*fpow(10,t-1);
        if(N>m)N-=m;
        else break;
        ++l;
    }
    int t=(l+1)>>1;
    int len=0;
    N-=1;
    while(N)a[++len]=N%10,N/=10;
    a[t]+=1;
    for(int i=t;i;--i)printf("%d",a[i]);
    for(int i=1+(l&1);i<=t;++i)printf("%d",a[i]);
    puts("");
    return 0;
}

E - Sinking Land

有一个\(H\times W\)的岛屿,周围被大海环绕。
这个岛屿可以被分成\(H\times W\)个\(1\times 1\)的方块,\((i,j)\)方块的高度是\(A_{i,j}\)。
第\(i\)时刻,海平面高度是\(i\),如果一个方块与海相邻且高度不超过海平面,则会被淹没。
给定\(Y\),回答\(1-Y\)时刻,每个时刻还未被淹没的方块数量。

把所有和海面相邻的方块给丢进队列里面BFS,每次暴力枚举时间。这样子时间复杂度是\(O(Y\times 2(H+W))\),复杂度的数量级其实是没有问题的,但是常数比较大,可能无法通过。

用优先队列优化上述过程,每次取最接近被淹没的方块出来,这样子可以优化掉时间这一维度,可以做到\(O(HW)\)。

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<vector>
using namespace std;
struct Node
{
    int x,y,t;
    bool operator<(const Node &a)const{
        return t>a.t;
    }
};
priority_queue<Node> Q;
const int MAX=1005;
inline int read()
{
    int x=0;bool t=false;char ch=getchar();
    while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
    if(ch=='-')t=true,ch=getchar();
    while(ch>='0'&&ch<='9')x=x*10+ch-48,ch=getchar();
    return t?-x:x;
}
int d[4][2]={0,1,0,-1,1,0,-1,0};
int H,W,Y,A[MAX][MAX];
bool vis[MAX][MAX];
int ans[100100];
int main()
{
    H=read();W=read();Y=read();
    for(int i=1;i<=H;++i)
        for(int j=1;j<=W;++j)
            A[i][j]=read();
    for(int i=1;i<=H;++i)
        for(int j=1;j<=W;++j)
            vis[i][j]=false;
    for(int i=1;i<=H;++i)
        for(int j=1;j<=W;++j)
            if(i==1||j==1||i==H||j==W)
                vis[i][j]=true,Q.push((Node){i,j,A[i][j]});
    int T=0;
    while(!Q.empty())
    {
        Node now=Q.top();
        Q.pop();
        int x=now.x,y=now.y,t=now.t;
        T=max(T,t);
        ans[T]++;
        for(int i=0;i<4;++i)
        {
            int nx=x+d[i][0];
            int ny=y+d[i][1];
            if(nx>=1&&nx<=H&&ny>=1&&ny<=W)
                if(!vis[nx][ny])
                {
                    vis[nx][ny]=true;
                    Q.push((Node){nx,ny,A[nx][ny]});
                }
        }
    }
    for(int i=1;i<=Y;++i)ans[i]+=ans[i-1];
    for(int i=1;i<=Y;++i)printf("%d\n",H*W-ans[i]);
    return 0;
}

F - Palindromic Expression

给定一个数,问是否存在一个因数分解的方法,使得分解的结果可以列为一个只包含数字1-9*回文串。

暴力搜索!
如果当前的数字\(N\)自己本身就是一个不含零的回文数,那么直接返回。
否则的话,需要找到一对回文质因数,直接暴力枚举因数,检查是否有回文因数,如果有,那么递归处理即可。

#include<iostream>
#include<cmath>
#include<algorithm>
#include<string>
using namespace std;
#define ll long long 
ll N;
string dfs(ll N)
{
    string s=to_string(N);
    string s_rev=s;
    reverse(s_rev.begin(),s_rev.end());
    int l=s.length();
    bool zero_flag=false;
    for(int i=0;i<l;++i)if(s[i]=='0')zero_flag=true;
    if(!zero_flag&&s==s_rev)return s;
    for(int i=2,l=sqrt(N);i<=l;++i)
        if(N%i==0)
        {
            bool flag=true;
            int t=i,j=0;
            while(t)
            {
                if(t%10==0)flag=false;
                t/=10;
            }
            t=i;
            if(!flag)continue;
            while(t)j=j*10+t%10,t/=10;
            if((N/i)%j==0)
            {
                string ret=dfs(N/i/j);
                if(ret!="")
                    return to_string(i)+"*"+ret+"*"+to_string(j);
            }
        }
    return "";
}
int main()
{
    cin>>N;
    string ret=dfs(N);
    if(ret!="")cout<<ret<<endl;
    else cout<<-1<<endl;
    return 0;
}

G - Dynamic Scheduling

给定两个长度为\(n\)的序列D和P。
有\(Q\)个操作,每个操作形如c x y,将\(D_c\)改为\(x\),将\(P_c\)改为\(y\)。
每次修改完成之后,回答如下问题的答案:
有\(n\)个任务,每天可以做一个任务,如果一个任务在\(D_i\)天前被解决,则可以获得奖励\(P_i\)。问可以得到的最大奖励。

模拟费用流。用线段树维护区间堆进行贪心。

标签:AtCoder,ch,Beginner,int,long,using,include,363,回文
From: https://www.cnblogs.com/cjyyb/p/18314943

相关文章

  • AtCoder Beginner Contest 363 补题记录(A~F)
    难度:A<B<C<E≈F<<D做题顺序:A->B->C->F->E->D其实VP的时候perf还是有\(2000+\)的(虽然说D炸了),perf应该是\(2028\)左右Asignedmain(){intn;cin>>n;intcnt=0;do{++cnt;++......
  • AtCoder Beginner Contest 363
    A.PilingUp(\(\operatorname{Difficulty}11\))让你求某个数距离最近的一个\(k\times100\)的距离是多少.水.#include<bits/stdc++.h>usingnamespacestd;namespacehdk{ namespacefastio{ voidrule(boolsetting=false){std::ios::sync_with_stdio(setting);} ......
  • ABC 363 E - Sinking Land 题解
    用一个优先队列维护和海相邻的位置,每次海面上升就判断一下队列中海拔最低的那个位置会不会被淹没,如果会,就删除,同时它上下左右的位置也是和海相邻的(或者就在海里),把它们加进优先队列里,记得判断一下加入的格子曾经有没有被加入过队列,不要加重复了。点击开DconstintN=1099;int......
  • ABC 363 F - Palindromic Expression 题解
    下文中提到的数字都不包含0,注意把含0的数字特判掉。反转指各个数位倒过来,比如114514反转过后就是415411。注意到,答案一定是这样:数列\(a\)的各个数字相乘,乘以一个回文,再把数列\(a\)倒过来,每个数反转,再相乘。比如:2*57*184481*75*2,其中的数列\(a\)就是:257,中间的回文......
  • AtCoder Beginner Contest 360 ( A~D)
    A-AHealthyBreakfasthttps://atcoder.jp/contests/abc360/tasks/abc360_a水题题意:只要R在M左侧即可思路:因为只要三位,所以只需要判断R在第一位或M在最后一位,有重复的情况#include<iostream>#include<cmath>#include<algorithm>usingnamespacestd;intmain(){......
  • LeetCode 363. 矩形区域不超过 K 的最大数值和
    363.矩形区域不超过K的最大数值和给你一个 mxn 的矩阵 matrix 和一个整数 k ,找出并返回矩阵内部矩形区域的不超过 k 的最大数值和。题目数据保证总会存在一个数值和不超过 k 的矩形区域。示例1:输入:matrix=[[1,0,1],[0,-2,3]],k=2输出:2解释:蓝色边......
  • Equal Cut (AtCoder - arc100_b)(前缀和,思维)
    题目来源:https://atcoder.jp/contests/abc102/tasks/arc100_b?lang=en//题意:将一串数字分为四段,求出每段的总和,怎么分,才能让这四段的各自总和的极差最小?//思路:“实在是想不出来好的算法,只会暴力,当时想的枚举中间的那一刀,然后左右二分,但是感觉也不太好写,毕竟我总是被二分的边界......
  • Toyota Programming Contest 2024#7(AtCoder Beginner Contest 362)
    ⚪题和板题大赛/jk好像能切的样子,但是太菜了,唐了8罚。A-BuyaPen输出除去某个颜色以外,其他颜色代表的最大值。点击查看代码#include<bits/stdc++.h>usingnamespacestd;inta,b,c;strings;signedmain(){cin>>a>>b>>c;cin>>s;if(s[0]=='R')a=103......
  • Solution - Atcoder AGC022D Shopping
    考虑到不管怎么走,都是\(0\)最后又绕回\(0\),于是答案肯定是\(2L\)的倍数。那么考虑\(\frac{\operatorname{ans}}{2L}\)即可。那么对于\(t_i\),可以先让答案加上\(\lfloor\frac{t_i}{2L}\rfloor\),同时令\(t_i\leftarrowt_i\bmod2L\)。原因就是考虑到这被去除掉的\(2......
  • Toyota Programming Contest 2024#7(AtCoder Beginner Contest 362)
    这场比赛还是比较水的A,B,C跳过D题dij把点权和边权都转换为边权即可E题DP可以用\(map\)存一下等差数列的差先说\(O(n^4)\),\(f_{len,i,j,t}\)分别表示长度,现在在\(i\),上一个在\(j\)显然动态转移方程就有了\(f_{len,i,j,k}=\sum_{k=1}^{k=j-1}f_{len-1,j,k,t}\)点击查看......