bzoj 4111: [Wf2015]Keyboarding

来源:互联网 发布:淘宝怎么退货退款 编辑:程序博客网 时间:2024/05/20 09:21
傻逼广搜,我却想不出来.
f[i][j][k]表示位置ij,打完第k个字母的最少步骤,然后这个题卡内存,用动态内存或者压着内存开数组.
以后如果再看到网格图的题,要想到与每个点连边的只有4个.
#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>#include<queue>#define ll long long#define inf 1e9#define eps 1e-8#define mdusing namespace std;struct PP { int x,y;} a[55][55][4];struct QQ { int x,y,k,dep;};queue<QQ> q;int T[55][55];bool vis[55][55][10010];char s[55][55],st[10010];int n,m,L;int bfs(){    for (int i=1;i<=n;i++)      for (int j=1;j<=m;j++)      {        T[i][j]=0;        for (int k=i-1;k;k--)          if (s[k][j]!=s[i][j])          {            a[i][j][T[i][j]++]=(PP){k,j};            break;          }        for (int k=i+1;k<=n;k++)          if (s[k][j]!=s[i][j])          {            a[i][j][T[i][j]++]=(PP){k,j};            break;          }        for (int k=j-1;k;k--)          if (s[i][k]!=s[i][j])          {            a[i][j][T[i][j]++]=(PP){i,k};            break;          }        for (int k=j+1;k<=m;k++)          if (s[i][k]!=s[i][j])          {            a[i][j][T[i][j]++]=(PP){i,k};            break;          }      }    vis[1][1][0]=1; q.push((QQ){1,1,0,0});    while (!q.empty())    {        QQ d=q.front(); int x=d.x,y=d.y,k=d.k,dep=d.dep;        q.pop();        if (s[x][y]==st[k+1]&&!vis[x][y][k+1])        {            vis[x][y][k+1]=1;            if (k+1==L) return dep+1;            q.push((QQ){x,y,k+1,dep+1});        }        else        {            for (int t=0;t<T[x][y];t++)            {                int i=a[x][y][t].x,j=a[x][y][t].y;                if (!vis[i][j][k])                {                    vis[i][j][k]=1;                    q.push((QQ){i,j,k,dep+1});                }            }        }    }    return -1;} int main(){    scanf("%d%d",&n,&m);    for (int i=1;i<=n;i++)      scanf("%s",s[i]+1);    scanf("%s",st+1);    L=strlen(st+1); st[++L]='*';    printf("%d\n",bfs());    return 0;}


0 0
原创粉丝点击