質問C:トランスポートゲート

16913 ワード

翌日私を起こしたのは目覚まし時計ではなく、夢です!
テーマの説明はnnの行列で島を表して、島の中に陸地と水域があって、陸地は0で表して、水域は1で表して、あなたは陸地の上で歩くことしかできなくて、陸地の上で歩くのはいかなる費用を使う必要はありません.始点の座標(sx,sy)と終点座標(ex,ey)を指定し、この2つの点が必ず陸地であることを保証します.任意の2つの陸地に1つのトランスポートゲートを構築することができ、最大1つのトランスポートゲートしか構築できません.トランスポートゲートは2つの点を互いに達成することができ、費用は2点間の横座標、縦座標の差の2乗和、すなわち(sx-ex)2+(sy-ey)2です.始点から終点までの最小費用を求め、コンベアドアを建てずに直接終点に着くことができる場合は0とする.複数のテストデータを入力します.最初の行には、テストデータのグループ数を表す正の整数t(2≦t≦10)が入力される.第1行目には正の整数n(1≦n≦100)が入力される.2行目に開始座標sx,syを入力します.3行目に終点座標ex,eyを入力します.次のn行はnnの01行列を入力し、0と1の間にスペースがありません.詳細はサンプルを参照してください.出力は、テストデータのセットごとに1行を出力します.すなわち、整数は、そのセットのデータの最小費用を表します.サンプル入力Copy 3 5 1 5 5 00001 11111 00111 0010110 3 3 3 3 1 010 101 0102 1 2 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;
    }
}