问题 C: 传送门

第二天叫醒我的不是闹钟,是梦想!

题目描述
用一个nn的矩阵表示一个岛屿,岛屿中有陆地和水域,陆地用0表示,水域用1表示,你只能在陆地上行走,在陆地上行走不需要花费任何费用,给定起点的坐标(sx,sy)与终点坐标(ex,ey),保证这两个点必定是陆地。
你可以在任意两块陆地上建立一个传送门且最多只能建一个传送门,传送门可以使两个点互达,费用是两点间横坐标、纵坐标的差的平方和,即(sx-ex)2+(sy-ey)2。
求从起点起到终点的最小花费,若不需要建传送门可直接到达终点则花费为0。
输入
有多组测试数据。
第一行输入一个正整数t(2≤t≤10),表示测试数据的组数。
对于第组测试数据输入如下:
第一行输入一个正整数n(1≤n≤100)。
第二行输入起点坐标sx,sy。
第三行输入终点坐标ex,ey。
接下来的n行输入一个n
n的01矩阵,0与1之间无空格,详见样例。
输出
对于每组测试数据输出一行,即一个整数表示该组数据的最小花费。
样例输入 Copy
3
5
1 1
5 5
00001
11111
00111
00110
00110
3
1 3
3 1
010
101
010
2
1 1
2 2
00
10
样例输出 Copy
10
8
0
提示
对于100%的数据,2≤t≤10,1≤n≤100。

//比赛中一直段错误,一直没改出来。改写bfs了
//如果能走通就输出0,如果不行就把周围0的点记录一下,然后从终点再跑一下,再记录。然后公式求即可

#include<bits/stdc++.h>
using namespace std;
const int N=110;
int sx,sy,ex,ey,n;
int dx[4]={1,0,-1,0};
int dy[4]={0,-1,0,1};
int vis[N][N],f,cnt;
char s[N][N];
struct node
{
  int x,y;
}a[1000],b[10000];
void bfs(int sx,int sy,int ex,int ey,node a[],int &cnt ,int f)
{
  queue<node>q;
  memset(vis,0,sizeof vis);
  vis[sx][sy]=1;
  q.push(node{sx,sy});
  a[++cnt]=node{sx,sy};
  while(q.size())
  {
    node t=q.front();
    q.pop();
    if(t.x==ex&&t.y==ey) {f=1;return ;}
    for(int i=0;i<4;i++)
    {
    //  cout<<"#####"<
      int x=t.x+dx[i];
      int y=t.y+dy[i];
    //  cout<
      if(x<1||x>n||y<1||y>n||s[x][y]=='1'||vis[x][y]==1) continue;
    //  cout<
      vis[x][y]=1;
      q.push(node{x,y});
      a[++cnt]=node{x,y};
    }
  }
}
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
      int f=0;
      cin>>n;
      cin>>sx>>sy>>ex>>ey;
      int cnt1=0,cnt2=0;
      for(int i=1;i<=n;i++) cin>>(s[i]+1);
      bfs(sx,sy,ex,ey,a,cnt1,f);
      if(f==1){ puts("0");continue;}
      f=0;
      bfs(ex,ey,sx,sy,b,cnt2,f);
      int minv=0x3f3f3f3f;
    //  for(int )
      for(int i=1;i<=cnt1;i++)
        for(int j=1;j<=cnt2;j++)
           minv=min(minv,(a[i].x-b[j].x)*(a[i].x-b[j].x)+(a[i].y-b[j].y)*(a[i].y-b[j].y));
      cout<<minv<<endl;
    }
}



你可能感兴趣的:(UPC)