CF1065D Three Pieces

题目描述:给出一个n*n的棋盘,棋盘上每个格子有一个值。你有一个子,要求将这个子从1移到n*n(去k时可以经过比k大的点)。

开局时它可以作为车,马,相(国际象棋)。每走一步耗费时间1。你也可以中途将它换为车,马,相(国际象棋),耗费时间1。

求最短时间,以及保证最短时间的最少替换次数。

题解:

一道恶心人的搜索题。对于每个点分为n*n*3种状态,表示当前已经经过1 ~ k,当前是车 / 马 / 相。

对于每个状态讨论做车 / 马 / 相怎么走,以及将它换成另外两种的情况。

代码(已经不想再写一遍了):

#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 15
int n,mp[N][N],rx,ry,lx,ly;
int dis[N][N][N*N][3],f[N][N][N*N][3];
bool vis[N][N][N*N][3];
struct node
{
    int x,y,d,typ;
    node(){}
    node(int x,int y,int d,int typ):x(x),y(y),d(d),typ(typ){}
}tp;
queue<node>q;
int dx[8]={-2,-2,-1,-1,1,1,2,2};
int dy[8]={-1,1,-2,2,-2,2,-1,1};
void ins(int x,int y,int d,int t)
{
    if(!vis[x][y][d][t])
    {
        vis[x][y][d][t]=1;
        q.push(node(x,y,d,t));
    }
}
int main()
{
    scanf("%d",&n);
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<n;j++)
        {
            scanf("%d",&mp[i][j]);
            if(mp[i][j]==1)
            {
                rx=i,ry=j;
            }else if(mp[i][j]==n*n)
            {
                lx=i,ly=j;
            }
        }
    }
    memset(dis,0x3f,sizeof dis);
    memset(f,0x3f,sizeof f);
    dis[rx][ry][1][0]=dis[rx][ry][1][1]=dis[rx][ry][1][2]=0;
    f[rx][ry][1][0]=f[rx][ry][1][1]=f[rx][ry][1][2]=0;
    q.push(node(rx,ry,1,0));q.push(node(rx,ry,1,1));q.push(node(rx,ry,1,2));
    vis[rx][ry][1][0]=vis[rx][ry][1][1]=vis[rx][ry][1][2]=1;
    int x,y,d,t,tx,ty,dd;
    while(!q.empty())
    {
        tp=q.front();
        q.pop();
        x=tp.x,y=tp.y,d=tp.d,t=tp.typ;
        vis[x][y][d][t]=0;
        if(t==0)
        {
            for(int i=0;i<n;i++)
            {
                dd = d+(mp[i][y]==d+1);
                if(dis[i][y][dd][t]>dis[x][y][d][t]+1)
                {
                    dis[i][y][dd][t]=dis[x][y][d][t]+1;
                    f[i][y][dd][t]=f[x][y][d][t];
                    ins(i,y,dd,t);
                }else if(dis[i][y][dd][t]==dis[x][y][d][t]+1)
                {
                    if(f[i][y][dd][t]>f[x][y][d][t])
                    {
                        f[i][y][dd][t]=f[x][y][d][t];
                        ins(i,y,dd,t);
                    }
                }
                dd = d+(mp[x][i]==d+1);
                if(dis[x][i][dd][t]>dis[x][y][d][t]+1)
                {
                    dis[x][i][dd][t]=dis[x][y][d][t]+1;
                    f[x][i][dd][t]=f[x][y][d][t];
                    ins(x,i,dd,t);
                }else if(dis[x][i][dd][t]==dis[x][y][d][t]+1)
                {
                    if(f[x][i][dd][t]>f[x][y][d][t])
                    {
                        f[x][i][dd][t]=f[x][y][d][t];
                        ins(x,i,dd,t);
                    }
                }
            }
            if(dis[x][y][d][1]>dis[x][y][d][0]+1)
            {
                dis[x][y][d][1]=dis[x][y][d][0]+1;
                f[x][y][d][1]=f[x][y][d][0]+1;
                ins(x,y,d,1);
            }else if(dis[x][y][d][1]==dis[x][y][d][0]+1)
            {
                if(f[x][y][d][1]>f[x][y][d][0]+1)
                {
                    f[x][y][d][1]=f[x][y][d][0]+1;
                    ins(x,y,d,1);
                }
            }
            if(dis[x][y][d][2]>dis[x][y][d][0]+1)
            {
                dis[x][y][d][2]=dis[x][y][d][0]+1;
                f[x][y][d][2]=f[x][y][d][0]+1;
                ins(x,y,d,2);
            }else if(dis[x][y][d][2]==dis[x][y][d][0]+1)
            {
                if(f[x][y][d][2]>f[x][y][d][0]+1)
                {
                    f[x][y][d][2]=f[x][y][d][0]+1;
                    ins(x,y,d,2);
                }
            }
        }else if(t==1)
        {
            for(int i=0;i<8;i++)
            {
                tx = x+dx[i],ty = y+dy[i];
                if(tx<0||ty<0||tx>=n||ty>=n)continue;
                dd = d+(mp[tx][ty]==d+1);
                if(dis[tx][ty][dd][t]>dis[x][y][d][t]+1)
                {
                    dis[tx][ty][dd][t]=dis[x][y][d][t]+1;
                    f[tx][ty][dd][t]=f[x][y][d][t];
                    ins(tx,ty,dd,t);
                }else if(dis[tx][ty][dd][t]==dis[x][y][d][t]+1)
                {
                    if(f[tx][ty][dd][t]>f[x][y][d][t])
                    {
                        f[tx][ty][dd][t]=f[x][y][d][t];
                        ins(tx,ty,dd,t);
                    }
                }
            }
            if(dis[x][y][d][0]>dis[x][y][d][1]+1)
            {
                dis[x][y][d][0]=dis[x][y][d][1]+1;
                f[x][y][d][0]=f[x][y][d][1]+1;
                ins(x,y,d,0);
            }else if(dis[x][y][d][0]==dis[x][y][d][1]+1)
            {
                if(f[x][y][d][0]>f[x][y][d][1]+1)
                {
                    f[x][y][d][0]=f[x][y][d][1]+1;
                    ins(x,y,d,0);
                }
            }
            if(dis[x][y][d][2]>dis[x][y][d][1]+1)
            {
                dis[x][y][d][2]=dis[x][y][d][1]+1;
                f[x][y][d][2]=f[x][y][d][1]+1;
                ins(x,y,d,2);
            }else if(dis[x][y][d][2]==dis[x][y][d][1]+1)
            {
                if(f[x][y][d][2]>f[x][y][d][1]+1)
                {
                    f[x][y][d][2]=f[x][y][d][1]+1;
                    ins(x,y,d,2);
                }
            }
        }else
        {
            for(int i=1;x-i>=0&&y-i>=0;i++)
            {
                tx = x-i,ty = y-i;
                dd = d+(mp[tx][ty]==d+1);
                if(dis[tx][ty][dd][t]>dis[x][y][d][t]+1)
                {
                    dis[tx][ty][dd][t]=dis[x][y][d][t]+1;
                    f[tx][ty][dd][t]=f[x][y][d][t];
                    ins(tx,ty,dd,t);
                }else if(dis[tx][ty][dd][t]==dis[x][y][d][t]+1)
                {
                    if(f[tx][ty][dd][t]>f[x][y][d][t])
                    {
                        f[tx][ty][dd][t]=f[x][y][d][t];
                        ins(tx,ty,dd,t);
                    }
                }
            }
            for(int i=1;x+i<n&&y-i>=0;i++)
            {
                tx = x+i,ty = y-i;
                dd = d+(mp[tx][ty]==d+1);
                if(dis[tx][ty][dd][t]>dis[x][y][d][t]+1)
                {
                    dis[tx][ty][dd][t]=dis[x][y][d][t]+1;
                    f[tx][ty][dd][t]=f[x][y][d][t];
                    ins(tx,ty,dd,t);
                }else if(dis[tx][ty][dd][t]==dis[x][y][d][t]+1)
                {
                    if(f[tx][ty][dd][t]>f[x][y][d][t])
                    {
                        f[tx][ty][dd][t]=f[x][y][d][t];
                        ins(tx,ty,dd,t);
                    }
                }
            }
            for(int i=1;x-i>=0&&y+i<n;i++)
            {
                tx = x-i,ty = y+i;
                dd = d+(mp[tx][ty]==d+1);
                if(dis[tx][ty][dd][t]>dis[x][y][d][t]+1)
                {
                    dis[tx][ty][dd][t]=dis[x][y][d][t]+1;
                    f[tx][ty][dd][t]=f[x][y][d][t];
                    ins(tx,ty,dd,t);
                }else if(dis[tx][ty][dd][t]==dis[x][y][d][t]+1)
                {
                    if(f[tx][ty][dd][t]>f[x][y][d][t])
                    {
                        f[tx][ty][dd][t]=f[x][y][d][t];
                        ins(tx,ty,dd,t);
                    }
                }
            }
            for(int i=1;x+i<n&&y+i<n;i++)
            {
                tx = x+i,ty = y+i;
                dd = d+(mp[tx][ty]==d+1);
                if(dis[tx][ty][dd][t]>dis[x][y][d][t]+1)
                {
                    dis[tx][ty][dd][t]=dis[x][y][d][t]+1;
                    f[tx][ty][dd][t]=f[x][y][d][t];
                    ins(tx,ty,dd,t);
                }else if(dis[tx][ty][dd][t]==dis[x][y][d][t]+1)
                {
                    if(f[tx][ty][dd][t]>f[x][y][d][t])
                    {
                        f[tx][ty][dd][t]=f[x][y][d][t];
                        ins(tx,ty,dd,t);
                    }
                }
            }
            if(dis[x][y][d][0]>dis[x][y][d][2]+1)
            {
                dis[x][y][d][0]=dis[x][y][d][2]+1;
                f[x][y][d][0]=f[x][y][d][2]+1;
                ins(x,y,d,0);
            }else if(dis[x][y][d][0]==dis[x][y][d][2]+1)
            {
                if(f[x][y][d][0]>f[x][y][d][2]+1)
                {
                    f[x][y][d][0]=f[x][y][d][2]+1;
                    ins(x,y,d,0);
                }
            }
            if(dis[x][y][d][1]>dis[x][y][d][2]+1)
            {
                dis[x][y][d][1]=dis[x][y][d][2]+1;
                f[x][y][d][1]=f[x][y][d][2]+1;
                ins(x,y,d,1);
            }else if(dis[x][y][d][1]==dis[x][y][d][2]+1)
            {
                if(f[x][y][d][1]>f[x][y][d][2]+1)
                {
                    f[x][y][d][1]=f[x][y][d][2]+1;
                    ins(x,y,d,1);
                }
            }
        }
    }
    int ans = dis[lx][ly][n*n][0],tk=f[lx][ly][n*n][0];
    if(dis[lx][ly][n*n][1]<ans)
    {
        ans=dis[lx][ly][n*n][1];
        tk =f[lx][ly][n*n][1];
    }else if(dis[lx][ly][n*n][1]==ans)
    {
        tk=min(tk,f[lx][ly][n*n][1]);
    }
    if(dis[lx][ly][n*n][2]<ans)
    {
        ans=dis[lx][ly][n*n][2];
        tk =f[lx][ly][n*n][2];
    }else if(dis[lx][ly][n*n][2]==ans)
    {
        tk=min(tk,f[lx][ly][n*n][2]);
    }
    printf("%d %d\n",ans,tk);
    return 0;
}

 

posted @ 2018-10-31 07:25  LiGuanlin  阅读(241)  评论(0编辑  收藏  举报