AtCoder Grand Contest 033

为什么ABC那么多?建议Atcoder多出些ARC/AGC,好不容易才轮到AGC……

A

签到。就是以黑点为源点做多元最短路,由于边长是1直接bfs就好了,求最长路径。

#include<bits/stdc++.h>
using namespace std;
const int N=1007,dx[4]={0,0,1,-1},dy[4]={1,-1,0,0};
int n,m,ans,qs,qe,d[N][N],qx[N*N],qy[N*N];
char mp[N][N];
int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)scanf("%s",mp[i]+1);
    for(int i=1;i<=n;i++)
    for(int j=1;j<=m;j++)
    if(mp[i][j]=='.')d[i][j]=1e9;
    else d[i][j]=0,qx[qe]=i,qy[qe++]=j;
    while(qs<qe)
    {
        int x=qx[qs],y=qy[qs++];
        for(int i=0;i<4;i++)
        {
            int u=x+dx[i],v=y+dy[i];
            if(u<1||u>n||v<1||v>m||d[u][v]<=d[x][y]+1)continue;
            d[u][v]=d[x][y]+1,ans=max(ans,d[u][v]);
            qx[qe]=u,qy[qe++]=v;
        }
    }
    cout<<ans<<endl;
}
View Code

B

实际上上下和左右可以分开算。假设只有U和D,那么所有U/D操作结束后,若保留在棋盘,则在区间[L,R],于是根据是先手还是后手的操作,更改区间,若区间在操作途中为空或最终区间不包含棋子所在行/列,则先手获胜,反之后手获胜

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+7;
int n,m,p,sr,sc;
char s[N],t[N];
bool walk1()
{
    int L=1,R=n;
    for(int i=p;i;i--)
    {
        if(t[i]=='U')R=min(n,R+1);else if(t[i]=='D')L=max(1,L-1);
        if(s[i]=='U')L++;else if(s[i]=='D')R--;
        if(L>R)return 1;
    }
    return (sr<L||sr>R);
}
bool walk2()
{
    int L=1,R=m;
    for(int i=p;i;i--)
    {
        if(t[i]=='L')R=min(m,R+1);else if(t[i]=='R')L=max(1,L-1);
        if(s[i]=='L')L++;else if(s[i]=='R')R--;
        if(L>R)return 1;
    }
    return (sc<L||sc>R);
}
int main()
{
    scanf("%d%d%d%d%d",&n,&m,&p,&sr,&sc);
    scanf("%s",s+1);
    scanf("%s",t+1);
    if(walk1()||walk2())puts("NO");
    else puts("YES");
}
View Code

C

发现每次操作对树的改变只有2种:1、删去所有叶节点(n=2时不可使用)。2、保留其中一个叶节点,删去其他点(n=1时不可使用)。开始瞎蒙个SG函数的错误结论上去,白掉5min。然后发现树等价于长为直径的链上游戏,于是DP链长度为i时先手是否必胜即可。

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+7;
int n,f[N],dep[N];
vector<int>G[N];
void dfs(int u,int fa)
{
    for(int i=0;i<G[u].size();i++)
    if(G[u][i]!=fa)dep[G[u][i]]=dep[u]+1,dfs(G[u][i],u);
}
int main()
{
    scanf("%d",&n);
    f[0]=1,f[1]=0;
    for(int i=2;i<=n;i++)if(f[i-1]&&f[i-2])f[i]=0;else f[i]=1;
    for(int i=1,x,y;i<n;i++)scanf("%d%d",&x,&y),G[x].push_back(y),G[y].push_back(x);
    dfs(1,0);
    int t=1;
    for(int i=2;i<=n;i++)if(dep[i]>dep[t])t=i;
    for(int i=1;i<=n;i++)dep[i]=0;
    dfs(t,0);
    t=0;
    for(int i=1;i<=n;i++)t=max(t,dep[i]);
    if(f[t])puts("First");else puts("Second");
}
View Code

DEF

result:rank217 rating+=47 now_rating=1925

猜你喜欢

转载自www.cnblogs.com/hfctf0210/p/10812556.html
今日推荐