kuangbin专题一简单搜索(下)


注意此处提供了链接

kuangbin专题总
kuangbin专题1

8. 罐子

问题描述

给你两个罐子,容积分别为 $A$ 升和 $B$ 升。
现在,你可以进行如下三种操作:

  • FILL(i),将罐子$i$($1\leqslant i \leqslant 2$)灌满水。
  • DROP(i),将罐子 $i$($1\leqslant i \leqslant 2$)清空。
  • POUR(i,j),将罐子 $i$ 中的水倒向罐子 $j$,直到罐子 $i$ 空了或罐子 $j$ 满了为止。
    请问,至少多少次操作后,可以使得其中一个罐子里恰好有 $C$ 升水。
输入格式

共一行,三个整数 $A,B,C$。

输出格式

如果无解,则输出一行 impossible 即可。
否则,第一行输出一个整数,表示最少操作次数。
随后按顺序每行输出一个操作指令,格式参考题面。

数据范围

$1\leqslant A,B,C \leqslant 100$,
$C \leqslant max(A,B)$。

输入样例

$3$ $5$ $4$

输出样例

$6$
FILL(2)
POUR(2,1)
DROP(1)
POUR(2,1)
FILL(2)
POUR(2,1)

思路

基于bfs的思想,将两个杯子分别看作坐标系中的$x$和$y$,去跑bfs即可,此时无非就6种情况,倒满$A$(来源于$B$或外界倒满),倒空$A$,倒满$B$(来源于$A$或外界倒满),倒空$B$.

代码

#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>

#define MAXN 110

using namespace std;

int A,B,C;
struct node{
    int x;
    int y;
    int step;
    string op;
};
string res[6]={"FILL(1)", "FILL(2)", "DROP(1)","DROP(2)","POUR(1,2)","POUR(2,1)"};

int vis[MAXN][MAXN];

void bfs()
{
    queue<node> q;
    q.push({0,0,0,""});
    vis[0][0]=1;

    while(q.size()>0)
    {
        node temp=q.front();
        q.pop();
        if(temp.x==C||temp.y==C)
        {
            //cout << temp.op << "***" << endl;
            cout << temp.step << endl;
            for(int i=0;i<temp.step;i++)
                cout << res[temp.op[i]] << endl; 
            return ;
        }
        int temp1=min(temp.x,B-temp.y);
        int temp2=min(temp.y,A-temp.x);
        //倒满,倒空,A->B,B->A
        int dir[6][2]={{A-temp.x,0},{0,B-temp.y},{-temp.x,0},{0,-temp.y},{-temp1,temp1},{temp2,-temp2}};
        for(int i=0;i<=5;i++)
        {
            int dx=temp.x+dir[i][0],dy=temp.y+dir[i][1];
            if(vis[dx][dy]==0)
            {
                char temp_op=i;
                string s=temp.op+temp_op;
                q.push({dx,dy,temp.step+1,s});
                vis[dx][dy]=1;
            }
        }
    }
    printf("impossible\n");
}

int main()
{
    scanf("%d %d %d",&A,&B,&C);
    bfs();
    return 0;
}

9. 点火游戏

问题描述

给定一个 $N$ 行 $M$ 列的方格矩阵。
其中一部分方格是草地,其余部分是空地。
草地能够被燃烧,空地不会。
当某个草地在 $t$ 时刻被点燃时,其上下左右四个方向的相邻方格中的草地方格也会在 $t+1$ 时刻被点燃。
注意,空地方格无论如何都不可能被点燃。
现在,你可以选择最多两个草地,将它们点燃。
请你计算,使得所有草地都被点燃所需花费的最少时间。

输入格式

第一行包含整数 $T$,表示共有 $T$ 组测试数据。
每组数据第一行包含两个整数 $N,M$。
接下来 $N$ 行,包含一个 $N \times M$ 的字符矩阵,# 表示草地,. 表示空地。

输出格式

每组数据输出一个结果,每个结果占一行。
结果表示为 Case x: y,其中 $x$ 为组别编号(从 $1$ 开始),$y$ 点燃所有草地需要花费的最短时间。如果无法点燃所有草地或者所有方格都是空地则输出 $-1$。

数据范围

$1 \leqslant T \leqslant 100$,
$1 \leqslant N,M \leqslant 10$。

输入样例

$5$
$3$ $3$
.#.
###
.#.
$3$ $3$
.#.
#.#
.#.
$3$ $3$

#.#

$3$ $3$
###
..#
#.#
$3$ $3$


输出样例

Case $1$: $1$
Case $2$: $-1$
Case $3$: $0$
Case $4$: $2$
Case $5$: $-1$

思路

经典的bfs问题,此题可暴力枚举两个草地的情况(可能存在一个草堆的情况,在跑两重循环第二层应从$i$开始),无终止条件,在$bfs$跑完后判断当前燃烧的草堆的个数是否与所有的草堆个数相等,返回最长的时间,并每次取最小值.

代码

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <cstdio>

#define MAXN 15

using namespace std;

typedef pair<int,int> PII;
const int inf=0x3f3f3f3f;
int t,n,m,res,sum,vis[MAXN][MAXN];
char g[MAXN][MAXN];
struct node{
    int x;
    int y;
    int step;
};
int dir[4][2]={{-1,0},{0,1},{1,0},{0,-1}};

int bfs(PII a,PII b)
{
    queue<node> q;
    memset(vis,0,sizeof(vis));
    q.push({a.first,a.second,0});
    if(a!=b)
        q.push({b.first,b.second,0});
    vis[a.first][a.second]=vis[b.first][b.second]=1;

    int cnt=0,maxx=0;
    while(q.size()>0)
    {
        node temp=q.front();
        q.pop();
        cnt++;
        for(int i=0;i<=3;i++)
        {
            int dx=temp.x+dir[i][0],dy=temp.y+dir[i][1];
            if(dx>=1&&dx<=n&&dy>=1&&dy<=m&&vis[dx][dy]==0&&g[dx][dy]=='#')
            {
                maxx=max(maxx,temp.step+1);
                vis[dx][dy]=1;
                q.push({dx,dy,temp.step+1});   
            }
        }
    }
    if(cnt==sum)
        return maxx;
    return -1;
}

int main()
{
    scanf("%d",&t);
    int cas=1;
    while(t--)
    {
        vector<PII> v;
        res=inf;
        sum=0;
        scanf("%d %d",&n,&m);
        for(int i=1;i<=n;i++)
        {
            scanf("%s",g[i]+1);
            for(int j=1;j<=m;j++)
                if(g[i][j]=='#')
                    v.push_back({i,j}),sum++;
        }
        for(int i=0;i<sum;i++)
            for(int j=i;j<sum;j++)//注意此处是i,不是i+1,它有可能只有一堆
            {
                int temp=bfs(v[i],v[j]);
                if(temp!=-1)
                    res=min(res,temp);
            }
        if(res==inf)
            printf("Case %d: -1\n",cas++);
        else printf("Case %d: %d\n",cas++,res);
    }
    return 0;
}

10. 起火迷宫

问题描述

一个迷宫可以看作一个 $R$ 行 $C$ 列的方格矩阵。
其中一些方格是空地,用 . 表示,其他方格是障碍,用 # 表示。
开始时,乔位于一块空地之中。
迷宫中一些空地已经起火了,幸运的是火还没有蔓延至乔所在的位置。
为了避免被火烧伤,乔需要尽快逃离迷宫。
已知,乔每单位时间只能沿上下左右四个方向前进一格距离,并且在前进过程中,他不能进入障碍方格。
火每单位时间都会蔓延至其上下左右四个方向的相邻空地,但是火也会被障碍阻挡。
如果一个方格已经起火或者会在乔进入方格的那一时刻恰好起火,则该方格很危险,乔不能进入。
当乔进入到任意一个位于边界的空地方格时,他都可以再花费一单位时间,直接逃离迷宫。
请问,乔想要逃离迷宫,最少需要花费的时间。

输入格式

第一行包含整数 $T$,表示共有 $T$ 组测试数据。
每组数据第一行包含两个整数 $R,C$。
接下来 $R$ 行,包含一个 $R \times C$ 的字符矩阵。
矩阵中只包含以下四种字符:

  • # 表示障碍方格。
  • . 表示空地方格。
  • J 表示乔所在的空地方格,最多只有一个。
  • F 表示已经起火的空地方格。
输出格式

每组数据输出一行结果,一个整数表示逃离迷宫所需花费的最少时间,如果无法逃离迷宫,则输出 IMPOSSIBLE

数据范围

$1 \leqslant T \leqslant 10$,
$1 \leqslant R,C \leqslant 1000$。

输入样例

$2$
$4$ $4$
####
#JF#
#..#
#..#
$3$ $3$
###
#J.
#.F

输出样例

$3$
IMPOSSIBLE

思路

基于bfs思想,先把火的蔓延情况跑一遍$bfs$,然后把人(注意考虑他到达边界的情况和他能走的情况必然在火蔓延之前,即$t_{人}+1 < t_{火}$)的行走情况跑一遍$bfs$.

代码

#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>

#define MAXN 1010

using namespace std;

const int inf=0x3f3f3f3f;

typedef pair<int, int> PII;

int dir[4][2]={{0,-1},{1,0},{0,1},{-1,0}};

int t,n,m,sx,sy;
char g[MAXN][MAXN];
int dist[MAXN][MAXN];//火
int Dist[MAXN][MAXN];//人

vector<PII> v;

void bfs()
{
    queue<PII> q;
    for(int i=0;i<v.size();i++)
    {
        q.push({v[i].first,v[i].second});
        dist[v[i].first][v[i].second]=0;
    }
    while(q.size()>0)
    {
        PII temp=q.front();
        q.pop();
        for(int i=0;i<=3;i++)
        {
            int dx=temp.first+dir[i][0],dy=temp.second+dir[i][1];
            if(dx>=1&&dx<=n&&dy>=1&&dy<=m&&dist[dx][dy]==inf&&g[dx][dy]=='.')
            {
                dist[dx][dy]=dist[temp.first][temp.second]+1;
                q.push({dx,dy});
            }
        }
    }
}

int BFS()
{
    if(sx==1||sx==n||sy==1||sy==m)
        return 1;
    queue<PII> q;
    q.push({sx,sy});
    Dist[sx][sy]=0;
    while(q.size()>0)
    {
        PII temp=q.front();
        q.pop();
        if(temp.first==1||temp.first==n||temp.second==1||temp.second==m)
            return Dist[temp.first][temp.second]+1;
        for(int i=0;i<=3;i++)
        {
            int dx=temp.first+dir[i][0],dy=temp.second+dir[i][1];
            if(dx>=1&&dx<=n&&dy>=1&&dy<=m&&Dist[dx][dy]==inf&&g[dx][dy]=='.'&&Dist[temp.first][temp.second]+1<dist[dx][dy])
            {
                Dist[dx][dy]=Dist[temp.first][temp.second]+1;
                q.push({dx,dy});
            }
        }
    }
    return 0;
}

int main()
{
    cin >> t;
    while(t--)
    {
        memset(dist,0x3f,sizeof(dist));
        memset(Dist,0x3f,sizeof(Dist));
        v.clear();
        cin >> n >> m;
        for(int i=1;i<=n;i++)
        {
            cin >> g[i]+1;
            for(int j=1;j<=m;j++)
            {
                if(g[i][j]=='J')
                    sx=i,sy=j;
                else if(g[i][j]=='F')
                    v.push_back({i,j});
            }
        }
        
        bfs();//火
        int res=BFS();
        if(res!=0)
            cout << res << endl;
        else cout << "IMPOSSIBLE" << endl;
    }
    return 0;
}

11. 迷宫问题

问题描述

给定一个 $n \times n$ 的二维数组,如下所示:

int maze[5][5] = {
0, 1, 0, 0, 0,
0, 1, 0, 1, 0,
0, 0, 0, 0, 0,
0, 1, 1, 1, 0,
0, 0, 0, 1, 0,
};

它表示一个迷宫,其中的$1$表示墙壁,$0$表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的最短路线。
数据保证至少存在一条从左上角走到右下角的路径。

输入格式

第一行包含整数 $n$。
接下来 $n$ 行,每行包含 $n$ 个整数 $0$ 或 $1$,表示迷宫。

输出格式

输出从左上角到右下角的最短路线,如果答案不唯一,输出任意一条路径均可。
按顺序,每行输出一个路径中经过的单元格的坐标,左上角坐标为 $(0,0)$,右下角坐标为 $(n-1,n-1)$。

数据范围

$0 \leqslant n \leqslant 1000$

输入样例

$5$
$0$ $1$ $0$ $0$ $0$
$0$ $1$ $0$ $1$ $0$
$0$ $0$ $0$ $0$ $0$
$0$ $1$ $1$ $1$ $0$
$0$ $0$ $0$ $1$ $0$

输出样例

$0$ $0$
$1$ $0$
$2$ $0$
$2$ $1$
$2$ $2$
$2$ $3$
$2$ $4$
$3$ $4$
$4$ $4$

思路

基于bfs的思想,这题主要考察的是输出路径,可采取递归实现路径的输出,用$xx$数组记录当前点的前驱结点的横坐标,用$yy$数组记录当前点的前驱结点的纵坐标,此题我下标是从(1,1)开始的,输出时坐标应为$(x-1,y-1)$.

代码

#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <cstdio>

#define MAXN 1010

using namespace std;

int n;
int g[MAXN][MAXN];
int xx[MAXN][MAXN],yy[MAXN][MAXN];
int vis[MAXN][MAXN];
int dir[4][2]={{-1,0},{0,1},{1,0},{0,-1}};

struct node{
    int x;
    int y;
    int step;
};

int bfs()
{
    queue<node> q;
    q.push({1,1,0});
    vis[1][1]=1;

    while(q.size()>0)
    {
        node temp=q.front();
        q.pop();
        if(temp.x==n&&temp.y==n)
            return temp.step;
        for(int i=0;i<=3;i++)
        {
            int dx=temp.x+dir[i][0],dy=temp.y+dir[i][1];
            if(dx>=1&&dx<=n&&dy>=1&&dy<=n&&vis[dx][dy]==0&&g[dx][dy]==0)
            {
                //cout << dx << " " << dy << endl;
                vis[dx][dy]=1;
                q.push({dx,dy,temp.step+1});
                xx[dx][dy]=temp.x;
                yy[dx][dy]=temp.y;
            }
        }
    }
    return -1;
}

void pre_out(int x,int y)
{
    if(x!=1||y!=1)
    {
        pre_out(xx[x][y],yy[x][y]);
        printf("%d %d\n",x-1,y-1);
        return ;
    }
    printf("0 0\n");
}

int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            scanf("%d",&g[i][j]);
    int res=bfs();
    //cout << res << endl;
    pre_out(n,n);
    return 0;
}

12. 石油储备

问题描述

一片土地可以看作是一个 $n$ 行 $m$ 列的方格矩阵。
其中一些方格藏有石油,用 @ 表示,其余方格没有石油,用 * 表示。
每个方格都与其上、下、左、右、左上、右上、左下、右下八个方格视为相邻。
如果两个藏有石油的方格相邻,则它们被认为是处于同一片油田,否则它们被认为是处于不同油田。
请问,该土地中共有多少片油田。

输入格式

输入包含多组测试数据。
每组数据第一行包含两个整数 $n,m$。
接下来 $n$ 行,包含一个 $n$ 行 $m$ 列的字符矩阵,表示土地情况。
当输入一行 0 0 时,表示输入结束。

输出格式

每组数据输出一行,一个整数,表示油田数量。

数据范围

最多包含 $100$ 组数据。
$1 \leqslant n,m \leqslant 100$。

输入样例

$1$ $1$
*
$3$ $5$
*@*@*
**@**
*@*@*
$1$ $8$
@@****@*
$5$ $5$
****@
*@@*@
*@**@
@@@*@
@@**@
$0$ $0$

输出样例

$0$
$1$
$2$
$2$

思路

基于bfs的思想,一次枚举没有标记的石油方格,枚举的次数即为答案.

代码

#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <cstdio>

#define MAXN 110

using namespace std;

int n,m,cnt;
char g[MAXN][MAXN];
int vis[MAXN][MAXN];
struct node{
    int x;
    int y;
};
int dir[8][2]={{-1,0},{-1,1},{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1}};

void bfs(int x,int y)
{
    queue<node> q;
    q.push({x,y});
    vis[x][y]=1;
    while(q.size()>0)
    {
        node temp=q.front();
        q.pop();
        for(int i=0;i<=7;i++)
        {
            int dx=temp.x+dir[i][0],dy=temp.y+dir[i][1];
            if(dx>=1&&dx<=n&&dy>=1&&dy<=m&&vis[dx][dy]==0&&g[dx][dy]=='@')
            {
                q.push({dx,dy});
                vis[dx][dy]=1;
            }
        }
    }
}

int main()
{
    while(scanf("%d %d",&n,&m)!=EOF)
    {
        if(n==0&&m==0)
            break;
        memset(vis,0,sizeof(vis));
        cnt=0;
        for(int i=1;i<=n;i++)
            scanf("%s",g[i]+1);
        
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                if(g[i][j]=='@'&&vis[i][j]==0)
                    bfs(i,j),cnt++;
        printf("%d\n",cnt);
    }

    return 0;
}

13. 非常可乐

问题描述

大家一定觉的运动以后喝可乐是一件很惬意的事情,但是 $seeyou$ 却不这么认为。
因为每次当 $seeyou$ 买了可乐以后,阿牛就要求和 $seeyou$ 一起分享这一瓶可乐,而且一定要喝的和 $seeyou$ 一样多。
但 $seeyou$ 的手中只有两个杯子,它们的容量分别是 $N$ 毫升和 $M$ 毫升。
可乐的体积为 $S$ ($S<101$)毫升 (正好装满一瓶) ,它们三个之间可以相互倒可乐 (都是没有刻度的,且 $S=N+M,101>S>0,N>0,M>0$) 。
聪明的 $ACMER$ 你们说他们能平分吗?
如果能请输出倒可乐的最少的次数,如果不能输出 NO

输入格式

输入包含多组测试数据。
每组数据一行,三个整数 $S,N,M$。
当输入一行为 0 0 0 时,表示输入结束。

输出格式

每组数据输出一行结果,如果能够平分,则输出倒可乐的最少的次数,否则输出 NO

数据范围

$S=N+M,101>S>0,N>0,M>0$

输入样例

$7$ $4$ $3$
$4$ $1$ $3$
$0$ $0$ $0$

输出样例

NO
$3$

思路

与罐子那题类似,无非就多一维的bfs,注意从$i$倒入$j$,倒入的容积是$min(w[i],v[j]-w[j])$.
另给一种大佬的数论做法巨佬链接

代码

#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <cstdio>

#define MAXN 110

using namespace std;

int val[3];
int vis[MAXN][MAXN][MAXN];
struct node{
    int w[3];
    int step;
};

int bfs()
{
    memset(vis,0,sizeof(vis));
    queue<node> q;
    q.push({val[0],0,0,0});
    vis[val[0]][0][0]=1;
    while(q.size()>0)
    {
        node temp=q.front();
        q.pop();
        if(temp.w[0]==temp.w[2]&&temp.w[1]==0)
            return temp.step;
        for(int i=0;i<=2;i++)
            for(int j=0;j<=2;j++)
            {
                if(i!=j)
                {
                    node tempp=temp;
                    int minx=min(tempp.w[i],val[j]-tempp.w[j]);//从i->j倒
                    tempp.w[i]-=minx,tempp.w[j]+=minx;
                    if(vis[tempp.w[0]][tempp.w[1]][tempp.w[2]]==0)
                    {
                        //cout << tempp.w[0] << " " << tempp.w[1] << " " << tempp.w[2] << endl;
                        tempp.step++;
                        q.push(tempp);
                        vis[tempp.w[0]][tempp.w[1]][tempp.w[2]]=1;
                    }
                }
            }
    }
    return -1;
}

int main()
{
    while(scanf("%d %d %d",&val[0],&val[1],&val[2])!=EOF)
    {
        if(val[0]==0&&val[1]==0&&val[2]==0)
            break;
        if(val[0]%2==1)
            printf("NO\n");
        else
        {
            if(val[1]>val[2])
                swap(val[1],val[2]);
            int res=bfs();
            if(res==-1)
                printf("NO\n");
            else printf("%d\n",res);
        }
    }
    return 0;
}

14. 找路

问题描述

给定一个 $n$ 行 $m$ 列的方格矩阵。
其中有些方格是空地(可以进入),有些方格是餐厅(可以进入),有些方格是障碍(不可进入)。
开始时,小 $Y$ 和小 $M$ 各自位于一个空地方格中。
每个人都可以沿上下左右四个方向进行移动,移动一格距离需要花费 $11$ 分钟时间。
他们希望选择一家餐厅进行聚餐,要求两人从各自出发点到达该餐厅所花费的时间之和尽可能小。
输出这个最小时间和。

输入格式

输入包含多组测试数据。
每组数据第一行包含两个整数 $n,m$。
接下来 $n$ 行,包含一个 $n×m$ 的字符矩阵。
矩阵中只包含以下五种字符:

  • # 表示障碍方格。
  • . 表示空地方格。
  • Y 表示小 $Y$ 所在的空地方格,有且仅有一个。
  • M 表示小 $M$ 所在的空地方格,有且仅有一个。
  • @ 表示餐厅。
输出格式

每组数据输出一行答案,表示最小时间和。
保证一定有解。

数据范围

最多包含 $100$ 组数据。
$2 \leqslant n,m \leqslant 200$。

输入样例

$4$ $4$
Y.#@
….
.#..
@..M
$4$ $4$
Y.#@
….
.#..
@#.M
$5$ $5$
Y..@.
.#…
.#…
@..M.
#…#

输出样例

$66$
$88$
$66$

思路

分别跑两个人的$bfs$,用$dist1$数组存储第一个人的行走情况,用$dist2$数组存储第二个人的行走情况,最后枚举所有的餐馆取$11 \times (dist1+dist2)$最小值即可.

代码

#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
#include <algorithm>
#include <vector>

#define MAXN 210

using namespace std;

const int inf=0x3f3f3f3f;
int n,m;
struct node{
    int x;
    int y;
};
int sx1,sy1,sx2,sy2;
char g[MAXN][MAXN];
int dist1[MAXN][MAXN],dist2[MAXN][MAXN],dist[MAXN][MAXN];
int dir[4][2]={{-1,0},{0,1},{1,0},{0,-1}};


void bfs(int sx,int sy)
{
    //memset(dist,0x3f,sizeof(dist));
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            dist[i][j]=inf;
    queue<node> q;
    q.push({sx,sy});
    dist[sx][sy]=0;
    while(q.size()>0)
    {
        node temp=q.front();
        q.pop();

        for(int i=0;i<=3;i++)
        {
            int dx=temp.x+dir[i][0],dy=temp.y+dir[i][1];
            if(dx>=1&&dx<=n&&dy>=1&&dy<=m&&dist[dx][dy]==inf&&g[dx][dy]!='#')
            {
                q.push({dx,dy});
                dist[dx][dy]=dist[temp.x][temp.y]+1;
            }
        }
    }
}

int main()
{
    while(scanf("%d %d",&n,&m)!=EOF)
    {
        vector<node> v;
        for(int i=1;i<=n;i++)
        {
            scanf("%s",g[i]+1);
            for(int j=1;j<=m;j++)
            {
                if(g[i][j]=='Y')
                    sx1=i,sy1=j;
                else if(g[i][j]=='M')
                    sx2=i,sy2=j;
                else if(g[i][j]=='@')
                    v.push_back({i,j});
            }
        }
        bfs(sx1,sy1);
        //memcpy(dist1,dist,sizeof(dist));
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                dist1[i][j]=dist[i][j];
        bfs(sx2,sy2);
        //memcpy(dist2,dist,sizeof(dist));
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                dist2[i][j]=dist[i][j];
        int res=inf;
        for(int i=0;i<v.size();i++)
            res=min(res,11*(dist1[v[i].x][v[i].y]+dist2[v[i].x][v[i].y]));
        printf("%d\n",res);
    }
    return 0;
}

文章作者: 保底不歪抽早柚
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 保底不歪抽早柚 !
评论
  目录