【6.28校内test】T1 Jelly的难题1

Jelly的难题【题目链接】

废话一句:今天中考出成绩,感觉大家考的都超级棒,不管怎样,愿大家成为最好的自己。

好了废话完了,下面是题解部分:


SOLUTION:

首先你可能发生的,是看不懂题:

定睛一看,这是个广搜!(然后非常幸运昨天刚做了一个广搜的题,然后我就会了)

首先先是输入部分,这个真的很毒瘤了,当sy已经去忙akT1的时候,我还在可怜的与读入作斗争(与读入抗争掉了大部分时间可还行)。读入很毒瘤,因为每个字符之间有空格,所以读入的时候要用while过滤。然后咱的读入好生毒瘤,看看就好啦(相信像ych这样的大佬肯定有更优的方法):

n=read();m=read();
    char ch=getchar();
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            while(ch==' '||ch=='
'||ch=='
') ch=getchar();
            a1[i][j]=ch;
            if(a1[i][j]=='*') x=i,y=j,a[i][j]=2;
            if(a1[i][j]=='#') a[i][j]=0;
            if(a1[i][j]=='o') a[i][j]=1;
            ch=getchar();
        }
    }

然后就是bfs部分了,其实就是一个标准的广搜板子,然后因为最近看了tarjan,我居然在bfs里用了时间戳可海星。

首先要说一直理解不了构造函数这种东西,所以一直都是写赋值函数,看看就好。

首先显然是把*(也就是打印机)的地方加进队列中,然后别忘记开vis记录已经走过了。

然后while(!q.empty()),每次取出队首,向四个方向扩展(当然前提是可以扩展因此记得写pan函数),然后对于最大时间以及卷子数量,我用了时间的理念,也就是记录访问顺序(当然并不是完全时间戳),进行储存与bfs,每次取出队首,然后四个方向尝试拓展,如果可以拓展,那么拓展,将其入队,并将新入队的结点的dfn值在被拓展出的结点的基础上+1,这样最大的dfn也就是最大的时间ans。然后还有如何算总共的卷子数,我的算法比较复杂,感觉过于麻烦了(看看就好啦),记录每个时间戳,然后用ans-时间戳+1,表示的就是这个结点的卷子数。然后加起来就好啦。

#include<bits/stdc++.h>

using namespace std;

inline int read(){
    int ans=0;
    char last,ch=getchar();
    while(ch<'0'||ch>'9') last=ch,ch=getchar();
    while(ch>='0'&&ch<='9') ans=(ans<<3)+(ans<<1)+ch-'0',ch=getchar();
    if(last=='-') ans=-ans;
    return ans;
}

int n,m,x,y;
int a[501][501];
int dx[4]={1,-1,0,0};
int dy[4]={0,0,-1,1};
char a1[501][501];
bool vis[501][501];
const int mod=19260817;

struct node{
    int x,y,dfn;
};

node fz(int x,int y,int dfn){
    node rtn;
    rtn.x=x;
    rtn.y=y;
    rtn.dfn=dfn;
    return rtn;
}

bool pan(int x,int y){//判断函数,保证行走合法
    return x>=1&&y>=1&&x<=n&&y<=m&&vis[x][y]==0&&a[x][y]==0;
}

queue<node> q;
void bfs(){
    q.push(fz(x,y,0));
    vis[x][y]=1;
    int ans=0,sum=0;
    int cnt=0,cz[300000];
    while(!q.empty()){
        node h=q.front();
        cz[++cnt]=h.dfn%mod;
        q.pop();
        for(int i=0;i<4;i++){
            int xx=h.x,yy=h.y,dfnn=h.dfn;
            if(pan(xx+dx[i],yy+dy[i])){
                xx+=dx[i];yy+=dy[i];
                q.push(fz(xx,yy,dfnn+1));
                vis[xx][yy]=1;
                if(dfnn+1>ans) ans=dfnn+1;
            }
        }
    }
    for(int i=2;i<=cnt;i++)//我太菜了的求卷子数法qwq
      sum=(sum%mod+ans%mod-cz[i]%mod+1)%mod;
    cout<<ans<<endl<<sum<<endl;
}

int main(){
    n=read();m=read();
    char ch=getchar();
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            while(ch==' '||ch=='
'||ch=='
') ch=getchar();
            a1[i][j]=ch;
            if(a1[i][j]=='*') x=i,y=j,a[i][j]=2;
            if(a1[i][j]=='#') a[i][j]=0;
            if(a1[i][j]=='o') a[i][j]=1;
            ch=getchar();
        }
    }
    bfs();
    return 0;
}

end-

原文地址:https://www.cnblogs.com/zhuier-xquan/p/11102578.html