Codeforces Round #436 (Div. 2)解题报告

这可能是我人生第一场计rating的cf啊。。怎么就炸的这么惨啊。

不得不说,题目确实很水啊。。然而我还是被艹翻了啊。

似乎前四题都太水了。于是扔代码跑。

Fair Game

#include <bits/stdc++.h>
#define gc getchar()
#define ll long long
#define N 109
using namespace std;
int a[N],vis[N],b[N];
int read()
{
    int x=1;
    char ch;
    while (ch=gc,ch<'0'||ch>'9') if (ch=='-') x=-1;
    int s=ch-'0';
    while (ch=gc,ch>='0'&&ch<='9') s=s*10+ch-'0';
    return x*s;
}
int main()
{
    int n=read(),num=0;
    for (int i=1;i<=n;i++)
        if (!vis[a[i]=read()]) vis[a[i]]=1,b[++num]=a[i];
        else vis[a[i]]++;
    if (num==2&&vis[b[1]]==vis[b[2]])
    {
        puts("YES");
        printf("%d %d\n",b[1],b[2]);
    }
    else
        puts("NO");
    return 0;
}

Polycarp and Letters

#include <bits/stdc++.h>
#define gc getchar()
#define ll long long
#define N 2009
using namespace std;
int read()
{
    int x=1;
    char ch;
    while (ch=gc,ch<'0'||ch>'9') if (ch=='-') x=-1;
    int s=ch-'0';
    while (ch=gc,ch>='0'&&ch<='9') s=s*10+ch-'0';
    return x*s;
}
char a[N],ch;
int ans=0,now=0,vis[N];
int n;
int main()
{
    n=read();
    scanf("%s",a+1);
    memset(vis,0,sizeof(vis));
    for (int i=1;i<=n;i++)
    {
        if (a[i]>='A'&&a[i]<='Z')
        {
            ans=max(ans,now);
            now=0;
            memset(vis,0,sizeof(vis));
        }
        else
        {
            if (!vis[a[i]]) vis[a[i]]=1,now++;
        }
    }
    ans=max(ans,now);
    printf("%d\n",ans);
    return 0;
}

Bus

#include <bits/stdc++.h>
#define gc getchar()
#define ll long long
using namespace std;
int read()
{
    int x=1;
    char ch;
    while (ch=gc,ch<'0'||ch>'9') if (ch=='-') x=-1;
    int s=ch-'0';
    while (ch=gc,ch>='0'&&ch<='9') s=s*10+ch-'0';
    return x*s;
}
int main()
{
    int a=read(),b=read(),f=read(),k=read();
    int rest=b,ans=0;
    if (k==1)
    {
        if (b<f||b<a-f)
        {
            puts("-1");
            return 0;
        }
        if (b>=a)
        {
            puts("0");
            return 0;
        }
        if (b<a)
        {
            puts("1");
            return 0;
        }
    }
    if (k==2)
    {
        if (b<f||b<2*(a-f))
        {
            puts("-1");
            return 0;
        }
        if (b>=2*a)
        {
            puts("0");
            return 0;
        }
        if (b>=2*a-f)
        {
            puts("1");
            return 0;
        }
        if (b<2*a-f)
        {
            puts("2");
            return 0;
        }
    }
    if (b<2*f||b<2*(a-f))
    {
        puts("-1");
        return 0;
    }
    for (int i=1;i<=k;i++)
    {
        if (rest>=a) rest-=a;
        else
        {
            ans++;
            if (i&1)
            {
                rest=b-(a-f);
            }
            else
            {
                rest=b-f;
            }
        }
        if (i==k) break;
        if (i&1)
        {
            if (rest<a-f)
            {
                ans++;
                rest=b-(a-f);
            }
        }
        else
        {
            if (rest<f)
            {
                ans++;
                rest=b-f;
            }
        }
    }
    printf("%d\n",ans);
    return 0;
}

Make a Permutation!

#include <bits/stdc++.h>
#define gc getchar()
#define ll long long
#define N 200009
using namespace std;
int n,a[N],last[N],b[N],vis[N];
priority_queue<int,vector<int>,greater<int> > q;
int read()
{
    int x=1;
    char ch;
    while (ch=gc,ch<'0'||ch>'9') if (ch=='-') x=-1;
    int s=ch-'0';
    while (ch=gc,ch>='0'&&ch<='9') s=s*10+ch-'0';
    return x*s;
}
int main()
{
    n=read();
    for (int i=1;i<=n;i++) a[i]=read();
    for (int i=1;i<=n;i++) last[a[i]]=i;
    for (int i=1;i<=n;i++)
        if (!last[i]) q.push(i);
    int ans=0;
    memset(vis,0,sizeof(vis));
    for (int i=1;i<=n;i++)
    {
        if (!vis[a[i]]&&last[a[i]]==i) b[i]=a[i],vis[a[i]]=1;
        else
        {
            while (vis[q.top()]) q.pop();
            int x=q.top();
            if (x<a[i]||vis[a[i]])
            {
                b[i]=x;
                vis[x]=1;
                ans++;
                q.pop();
            }
            else
            {
                b[i]=a[i];
                vis[a[i]]=1;
            }
        }
    }
    printf("%d\n",ans);
    for (int i=1;i<=n;i++) printf("%d%s",b[i],i==n?"\n":" ");
    return 0;
}

Fire

按照 di 从小到大排个序,然后01背包即可。
然而我记录方案居然是一维的,果然还是菜啊。

#include <bits/stdc++.h>
#define gc getchar()
#define ll long long
#define N 2009
#define M 20009
#define inf 0x3f3f3f3f
using namespace std;
int n,dp[M],vis[N][M],ans[N];
struct node
{
    int t,d,p,pos;
    bool operator <(const node &rhs) const
    {
        return d<rhs.d;
    }
}q[N];
int read()
{
    int x=1;
    char ch;
    while (ch=gc,ch<'0'||ch>'9') if (ch=='-') x=-1;
    int s=ch-'0';
    while (ch=gc,ch>='0'&&ch<='9') s=s*10+ch-'0';
    return x*s;
}
int main()
{
    n=read();
    for (int i=1;i<=n;i++)
    {
        q[i].t=read();
        q[i].d=read();
        q[i].p=read();
        q[i].pos=i;
    }
    sort(q+1,q+n+1);
    for (int i=1;i<=n;i++)
    {
        for (int j=q[i].d-1;j>=q[i].t;j--)
        {
            if (dp[j-q[i].t]+q[i].p>dp[j])
            {
                dp[j]=dp[j-q[i].t]+q[i].p;
                vis[i][j]=1;
            }
        }
    }
    int Ans=0,pos=0;
    for (int i=0;i<20000;i++)
        if (dp[i]>Ans)
        {
            Ans=dp[i];
            pos=i;
        }
    printf("%d\n",Ans);
    int m=0;
    for (int i=n;i;i--)
    {
        if (vis[i][pos])
        {
            ans[++m]=q[i].pos;
            pos-=q[i].t;
        }
    }
    printf("%d\n",m);
    for (int i=m;i;i--)
        printf("%d%s",ans[i],i==1?"\n":" ");
    if (!m) puts("");
    return 0;
}

Cities Excursions

大致思路是每个点跑出一棵树,然后倍增,树剖什么的跳一下就好了。
然而难点就是建树,要搞清楚环的特殊性(环上点后来出去的边都是到不了的)。最重要的是要时刻考虑到环可能扩大影响区域。。

#include <bits/stdc++.h>
#define gc getchar()
#define ll long long
#define N 3002
using namespace std;
int n,m,q,first[N],number,vis[N];
int now_cir;
struct edge
{
    int to,next,vis;
    void add(int x,int y)
    {
        to=y,next=first[x],first[x]=number;
    }
}e[N<<1];
bool cmp(int x,int y)
{
    return e[x].to<e[y].to;
}
struct Tree
{
    int size[N],Mson[N],fa[N],top[N],deep[N],dfn[N],id[N],cnt;
    void init()
    {
        memset(fa,0,sizeof(fa));
        memset(deep,0,sizeof(deep));
        deep[0]=size[0]=cnt=0;
    }
    void dfs1(int x)
    {
        Mson[x]=0,size[x]=1;
        for (int i=first[x];i;i=e[i].next)
            if (e[i].vis)
            {
                dfs1(e[i].to),size[x]+=size[e[i].to];
                if (size[e[i].to]>size[Mson[x]]) Mson[x]=e[i].to;
            }
    }
    void dfs2(int x,int y)
    {
        id[dfn[x]=++cnt]=x,top[x]=y;
        if (Mson[x]) dfs2(Mson[x],y);
        for (int i=first[x];i;i=e[i].next)
            if (e[i].vis&&e[i].to!=Mson[x]) dfs2(e[i].to,e[i].to);
    }
    int qry(int y,int z)
    {
        z=deep[y]-z+1;
        if (z<=0) return -1;
        while (z>deep[y]-deep[top[y]]+1&&y)
        {
            z-=deep[y]-deep[top[y]]+1;
            y=fa[top[y]];
        }
        return id[dfn[y]-z+1];
    }
    void dfs(int x,bool flag)
    {
        if (!flag) deep[x]=deep[fa[x]]+1;
        vector<int> to;
        for (int i=first[x];i;i=e[i].next)
            if (vis[e[i].to]!=2&&vis[e[i].to]!=1)
                to.push_back(i);
        sort(to.begin(),to.end(),cmp);
        vis[x]=flag?2:3;
        for (int i=0;i<(int)to.size();i++)
            if (vis[e[to[i]].to]==3)
            {
                if (!now_cir||deep[e[to[i]].to]<deep[now_cir])
                    now_cir=e[to[i]].to;
            }
            else
                if (!vis[e[to[i]].to])
                {
                    if (!now_cir) e[to[i]].vis=1,fa[e[to[i]].to]=x;
                    dfs(e[to[i]].to,(now_cir>0));
                }
        vis[x]=1;
        if (x==now_cir) now_cir=0;
    }
}t[N];
int read()
{
    int x=1;
    char ch;
    while (ch=gc,ch<'0'||ch>'9') if (ch=='-') x=-1;
    int s=ch-'0';
    while (ch=gc,ch>='0'&&ch<='9') s=s*10+ch-'0';
    return x*s;
}
int main()
{
    n=read(),m=read(),q=read();
    for (int i=1;i<=m;i++)
    {
        int x=read(),y=read();
        e[++number].add(x,y);
    }
    for (int i=1;i<=n;i++)
    {
        now_cir=0,t[i].init();
        for (int i=1;i<=number;i++) e[i].vis=0;
        memset(vis,0,sizeof(vis));
        t[i].deep[i]=1;
        t[i].dfs(i,0);
        t[i].dfs1(i),t[i].dfs2(i,i);
    }
    while (q--)
    {
        int x=read(),y=read(),k=read();
        if (!t[x].deep[y]) puts("-1");
        else printf("%d\n",t[x].qry(y,k));
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值